Skip to content

Commit acead3d

Browse files
authored
add web (#12)
* feat(openspec): add web platform export proposal Proposal to extend ExFig with native Web/React support: - CSS variables and TypeScript constants for colors - React TSX components via SVGR pattern for icons - Raw SVG/PNG asset export with barrel index files - New WebExport module following FlutterExport patterns * feat(web): add web platform export support * feat(web): add SVG to JSX converter for React components * feat(web): add SVG to JSX converter for React components
1 parent d335795 commit acead3d

46 files changed

Lines changed: 3831 additions & 15 deletions

Some content is hidden

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

.claude/EXFIG.toon

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
meta:
22
name: ExFig
33
version: current
4-
description: CLI tool for exporting Figma assets to iOS, Android, Flutter
4+
description: CLI tool for exporting Figma assets to iOS, Android, Flutter, Web
55
swift: 6.0
66
platforms: macOS 12.0+, Linux
77
license: MIT
@@ -54,7 +54,7 @@ commands:
5454
init:
5555
purpose: Generate starter config file
5656
options:
57-
platform: -p/--platform ios|android (required)
57+
platform: -p/--platform ios|android|flutter|web (required)
5858

5959
batch:
6060
purpose: Process multiple configs in parallel
@@ -107,13 +107,14 @@ commands:
107107
failFast: --fail-fast
108108
resume: --resume
109109

110-
modules[7]{name,path,purpose}:
110+
modules[8]{name,path,purpose}:
111111
ExFig,Sources/ExFig,CLI commands and orchestration
112112
ExFigCore,Sources/ExFigCore,Domain models and processors
113113
FigmaAPI,Sources/FigmaAPI,HTTP client with rate limiting
114114
XcodeExport,Sources/XcodeExport,iOS xcassets and Swift extensions
115115
AndroidExport,Sources/AndroidExport,Android XML and Compose code
116116
FlutterExport,Sources/FlutterExport,Flutter Dart code
117+
WebExport,Sources/WebExport,Web CSS variables and React/TypeScript
117118
SVGKit,Sources/SVGKit,SVG parsing and vector generation
118119

119120
keyDirectories:
@@ -132,7 +133,7 @@ configTypes:
132133
IconsConfiguration:
133134
purpose: Enum for backward-compatible icons config parsing
134135
cases: [single(Icons), multiple([IconsEntry])]
135-
platforms: [iOS, Android, Flutter]
136+
platforms: [iOS, Android, Flutter, Web]
136137
properties:
137138
entries: "[IconsEntry] - unified access to all entries"
138139
isMultiple: "Bool - true if array format"
@@ -145,7 +146,7 @@ configTypes:
145146
IconsLoaderConfig:
146147
purpose: Sendable struct for IconsLoader frame settings
147148
file: Sources/ExFig/Loaders/IconsLoader.swift
148-
factoryMethods: [forIOS, forAndroid, forFlutter, defaultConfig]
149+
factoryMethods: [forIOS, forAndroid, forFlutter, forWeb, defaultConfig]
149150

150151
keyFiles:
151152
cli: Sources/ExFig/ExFigCommand.swift
@@ -237,11 +238,12 @@ templates:
237238
ios[10]: UIColor+extension, Color+extension, UIFont+extension, Font+extension, UIImage+extension, Image+extension, Label, LabelStyle, LabelStyle+extension, header
238239
android[6]: colors.xml, Colors.kt, typography.xml, Typography.kt, Icons.kt, header
239240
flutter[4]: colors.dart, icons.dart, images.dart, header
241+
web[8]: theme.css, variables.ts, theme.json, Icon.tsx, types.ts, IconIndex.ts, Image.tsx, ImageIndex.ts, header
240242

241243
config:
242244
files: exfig.yaml, figma-export.yaml
243245
envVar: FIGMA_PERSONAL_TOKEN
244-
sections: figma, common, ios, android, flutter
246+
sections: figma, common, ios, android, flutter, web
245247
reference: CONFIG.md
246248

247249
buildCommands:
@@ -281,11 +283,12 @@ figmaAPI:
281283
tier3: 50-150 req/min
282284
docs: https://www.figma.com/developers/api
283285

284-
testTargets[7]{name,tests}:
286+
testTargets[8]{name,tests}:
285287
ExFigTests,CLI commands and loaders
286288
ExFigCoreTests,Domain models and processors
287289
XcodeExportTests,iOS export output
288290
AndroidExportTests,Android export output
289291
FlutterExportTests,Flutter export output
292+
WebExportTests,Web CSS and React/TypeScript output
290293
FigmaAPITests,API client and endpoints
291294
SVGKitTests,SVG parsing and code generation

CONFIG.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,64 @@ flutter:
325325
encoding: lossy
326326
# Encoding quality in percents. Only for lossy encoding.
327327
quality: 90
328+
329+
# [optional] Web export parameters (React/TypeScript)
330+
web:
331+
# Relative or absolute path to the output directory for generated files
332+
output: "./src/generated"
333+
# [optional] Path to the Stencil templates used to generate code
334+
templatesPath: "./templates"
335+
336+
# Parameters for exporting colors
337+
colors:
338+
# [optional] Output file name for CSS variables. Defaults to "theme.css"
339+
cssFile: "theme.css"
340+
# [optional] Output file name for TypeScript constants. Defaults to "variables.ts"
341+
tsFile: "variables.ts"
342+
# [optional] Output file name for JSON tokens. When specified, exports colors as JSON
343+
jsonFile: "tokens.json"
344+
345+
# Parameters for exporting icons
346+
# Can be a single object (legacy format) or an array of objects (new format)
347+
# Legacy format (single icons configuration):
348+
icons:
349+
# [optional] Where to place SVG icon assets (relative path)
350+
assetsDirectory: "assets/icons"
351+
# [optional] Generate React TSX components for each icon. Defaults to true
352+
generateReactComponents: true
353+
# [optional] Export types.ts with TypeScript interfaces. Defaults to true
354+
exportTypes: true
355+
# [optional] Icon size in pixels for viewBox. Defaults to 24
356+
iconSize: 24
357+
358+
# New format (multiple icons configurations from different Figma frames):
359+
# icons:
360+
# - figmaFrameName: Actions # Export icons from "Actions" frame
361+
# assetsDirectory: "assets/icons/actions"
362+
# generateReactComponents: true
363+
# iconSize: 24 # Icon size for viewBox
364+
# - figmaFrameName: Navigation # Export icons from "Navigation" frame
365+
# assetsDirectory: "assets/icons/nav"
366+
# generateReactComponents: true
367+
# iconSize: 20 # Different icon size for navigation
368+
369+
# Parameters for exporting images
370+
# Can be a single object (legacy format) or an array of objects (new format)
371+
# Legacy format (single images configuration):
372+
images:
373+
# [optional] Where to place image assets (relative path)
374+
assetsDirectory: "assets/images"
375+
# [optional] Generate React TSX components for each image. Defaults to true
376+
generateReactComponents: true
377+
378+
# New format (multiple images configurations from different Figma frames):
379+
# images:
380+
# - figmaFrameName: Illustrations
381+
# assetsDirectory: "assets/images/illustrations"
382+
# generateReactComponents: true
383+
# - figmaFrameName: Promo
384+
# assetsDirectory: "assets/images/promo"
385+
# generateReactComponents: true
328386
```
329387

330388
## Multiple Icons Configuration
@@ -392,6 +450,22 @@ When using multiple entries with the same Figma file:
392450
This means 17 icon entries with the same `lightFileId` result in only 1 Components API call (plus 1 Images API call per
393451
unique frame), not 17 separate calls.
394452

453+
### Web Icons Array Format
454+
455+
```yaml
456+
web:
457+
icons:
458+
- figmaFrameName: Actions
459+
assetsDirectory: assets/icons/actions
460+
generateReactComponents: true
461+
iconSize: 24
462+
- figmaFrameName: Navigation
463+
assetsDirectory: assets/icons/nav
464+
generateReactComponents: true
465+
exportTypes: true
466+
iconSize: 20
467+
```
468+
395469
## Multiple Colors Configuration
396470

397471
ExFig supports exporting colors from multiple Figma Variable collections in a single config file. This is useful when
@@ -493,6 +567,25 @@ flutter:
493567
className: ThemeColors
494568
```
495569

570+
### Web Colors Array Format
571+
572+
```yaml
573+
web:
574+
colors:
575+
- tokensFileId: abc123
576+
tokensCollectionName: Base Palette
577+
lightModeName: Light
578+
cssFile: base-theme.css
579+
tsFile: base-variables.ts
580+
- tokensFileId: def456
581+
tokensCollectionName: Theme Colors
582+
lightModeName: Light
583+
darkModeName: Dark
584+
cssFile: theme.css
585+
tsFile: theme-variables.ts
586+
jsonFile: theme-tokens.json
587+
```
588+
496589
## Multiple Images Configuration
497590

498591
ExFig supports exporting images from multiple Figma frames in a single config file. This is useful when your design
@@ -575,6 +668,19 @@ flutter:
575668
scales: [1, 2, 3]
576669
```
577670

671+
### Web Images Array Format
672+
673+
```yaml
674+
web:
675+
images:
676+
- figmaFrameName: Illustrations
677+
assetsDirectory: assets/images/illustrations
678+
generateReactComponents: true
679+
- figmaFrameName: Promo
680+
assetsDirectory: assets/images/promo
681+
generateReactComponents: true
682+
```
683+
578684
### Fallback Behavior
579685

580686
If `figmaFrameName` is not specified in an entry, it falls back to:

Package.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ let package = Package(
3535
"XcodeExport",
3636
"AndroidExport",
3737
"FlutterExport",
38+
"WebExport",
3839
"SVGKit",
3940
.product(name: "XcodeProj", package: "XcodeProj"),
4041
.product(name: "ArgumentParser", package: "swift-argument-parser"),
@@ -95,6 +96,15 @@ let package = Package(
9596
]
9697
),
9798

99+
// Exports resources to Web/React project
100+
.target(
101+
name: "WebExport",
102+
dependencies: ["ExFigCore", "Stencil", "StencilSwiftKit"],
103+
resources: [
104+
.copy("Resources/"),
105+
]
106+
),
107+
98108
// MARK: - Tests
99109

100110
.testTarget(
@@ -142,6 +152,12 @@ let package = Package(
142152
"FlutterExport", .product(name: "CustomDump", package: "swift-custom-dump"),
143153
]
144154
),
155+
.testTarget(
156+
name: "WebExportTests",
157+
dependencies: [
158+
"WebExport", .product(name: "CustomDump", package: "swift-custom-dump"),
159+
]
160+
),
145161
.testTarget(
146162
name: "SVGKitTests",
147163
dependencies: ["SVGKit", .product(name: "CustomDump", package: "swift-custom-dump")]

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
[![CI](https://github.com/alexey1312/ExFig/actions/workflows/ci.yml/badge.svg)](https://github.com/alexey1312/ExFig/actions/workflows/ci.yml)
66
[![Release](https://github.com/alexey1312/ExFig/actions/workflows/release.yml/badge.svg)](https://github.com/alexey1312/ExFig/actions/workflows/release.yml)
77
[![Docs](https://github.com/alexey1312/ExFig/actions/workflows/deploy-docc.yml/badge.svg)](https://alexey1312.github.io/ExFig/documentation/exfig)
8-
![Coverage](https://img.shields.io/badge/coverage-51.30%25-yellow)
8+
![Coverage](https://img.shields.io/badge/coverage-50.19%25-yellow)
99
[![License](https://img.shields.io/github/license/alexey1312/ExFig.svg)](LICENSE)
1010

11-
Command-line utility to export colors, typography, icons, and images from Figma to Xcode, Android Studio, and Flutter
12-
projects.
11+
Command-line utility to export colors, typography, icons, and images from Figma to Xcode, Android Studio, Flutter, and
12+
Web (React/TypeScript) projects.
1313

1414
Automatically sync your design system from Figma to code with support for Dark Mode, SwiftUI, UIKit, Jetpack Compose,
15-
and Flutter.
15+
Flutter, and React/TypeScript.
1616

1717
## Why ExFig?
1818

@@ -38,6 +38,7 @@ and Flutter.
3838
- 📱 SwiftUI and UIKit (iOS/macOS)
3939
- 🤖 Jetpack Compose and XML resources (Android)
4040
- 🦋 Flutter / Dart
41+
- 🌐 React / TypeScript (CSS variables, TSX components)
4142
- 🔧 Customizable code templates (Stencil)
4243

4344
### Export Formats

0 commit comments

Comments
 (0)