Výchozím cílem exportu figmascope je Jetpack Compose. To není náhodné — layoutový model Compose (Column, Row, Box, Modifier) se úzce mapuje na typy uzlů IR (stack, overlay, absolute, leaf). Vertikální stack ve Figmě je Column v Compose. Překlad je mechanický, což ho činí vhodným pro generování kódu řízeného agentem.
Tento průvodce podrobně pokrývá mapování IR na Compose, ukazuje skutečný fragment JSON s odpovídajícím Composable a vysvětluje vrstvu mapování tokenů.
Proč je Compose výchozím cílem
Tři strukturální důvody:
- Auto-layout ↔ Column/Row. Rámce Figmy s auto-layoutem (naprostá většina moderních designů Figmy) se exportují jako uzly
kind: "stack". Stack uzly mají vlastnostaxis—verticalse mapuje naColumn,horizontalse mapuje naRow. Jedná se o mapování 1:1 bez kroku interpretace. - Tokeny mezer ↔ hodnoty dp. Compose používá
Dppro všechny layoutové rozměry. Hodnoty tokenů vtokens.jsonjsou celá čísla bez jednotek (např.spacing.16 = 16), která se přímo mapují na16.dp. Žádná konverze, žádné škálování. - Tokeny barev ↔ Color composable. Hexadecimální hodnoty Figmy v
tokens.jsonse mapují naColor(0xFFrrggbb)jedinou transformací. Klíč tokenu se stane sémantickým názvem proměnné ve vašem tématu.
Typy uzlů IR a jejich mapování na Compose
| Typ IR | Vlastnosti | Primitivum Compose |
|---|---|---|
stack | axis: "vertical" | Column |
stack | axis: "horizontal" | Row |
overlay | vrstvené děti | Box |
absolute | x, y, width, height | Box s Modifier.offset(x.dp, y.dp) |
leaf | type: "text" | Text s TextStyle |
leaf | type: "rectangle" s výplní | Box(Modifier.background(Color(...))) |
Všechny typy uzlů mohou nést vlastnost spacing (mezera mezi dětmi) a objekt padding (nahoře/vpravo/dole/vlevo). Oba odkazují na klíče tokenů.
Podrobné mapování tokenů
Soubor tokens.json vypadá takto:
{
"spacing": {
"4": 4, "8": 8, "12": 12, "16": 16,
"20": 20, "24": 24, "32": 32, "48": 48
},
"radius": {
"4": 4, "8": 8, "12": 12, "16": 16, "full": 9999
},
"color": {
"7f5cfe": "#7F5CFE",
"1a1a2e": "#1A1A2E",
"f6f2ea": "#F6F2EA",
"ffffff": "#FFFFFF",
"e53935": "#E53935"
},
"typography": {
"heading.24": { "size": 24, "weight": 700, "lineHeight": 1.2 },
"body.14": { "size": 14, "weight": 400, "lineHeight": 1.5 },
"label.12": { "size": 12, "weight": 500, "lineHeight": 1.4 }
}
}
Pravidla mapování:
spacing.16→16.dpradius.12→RoundedCornerShape(12.dp)color.7f5cfe→Color(0xFF7F5CFE)(přidejte0xFFpro plnou průhlednost)typography.heading.24→TextStyle(fontSize = 24.sp, fontWeight = FontWeight.Bold, lineHeight = 28.8.sp)
Klíče tokenů jsou záměrně neprůhledné (hexadecimální řetězce pro barvy, číselné řetězce pro mezery), takže neovlivňují model směrem k žádné konkrétní konvenci pojmenování. Vaše téma Compose může mít pro ně aliasy na sémantická jména — colorPrimary, spacingMd — nezávisle na IR.
Skutečný příklad: JSON domovské obrazovky do Composable
Zde je zjednodušený IR domovské obrazovky. Vertikální stack s listem záhlaví a seznamem karet:
{
"name": "home",
"kind": "stack",
"axis": "vertical",
"spacing": "spacing.24",
"padding": { "top": "spacing.16", "right": "spacing.16",
"bottom": "spacing.16", "left": "spacing.16" },
"fill": "color.f6f2ea",
"children": [
{
"kind": "leaf",
"type": "text",
"stringRef": "home.title",
"typography": "typography.heading.24",
"fill": "color.1a1a2e"
},
{
"kind": "stack",
"axis": "vertical",
"spacing": "spacing.12",
"children": [
{
"kind": "overlay",
"radius": "radius.12",
"fill": "color.ffffff",
"padding": { "top": "spacing.16", "right": "spacing.16",
"bottom": "spacing.16", "left": "spacing.16" },
"children": [
{
"kind": "leaf",
"type": "text",
"stringRef": "home.card.label",
"typography": "typography.label.12",
"fill": "color.7f5cfe"
}
]
}
]
}
]
}
Odpovídající Composable — co by měl agent z tohoto IR vyprodukovat:
@Composable
fun HomeScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFF6F2EA))
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
Text(
text = stringResource(R.string.home_title),
style = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
lineHeight = 28.8.sp,
color = Color(0xFF1A1A2E)
)
)
Column(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Box(
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.background(Color(0xFFFFFFFF))
.padding(16.dp)
) {
Text(
text = stringResource(R.string.home_card_label),
style = TextStyle(
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
lineHeight = 16.8.sp,
color = Color(0xFF7F5CFE)
)
)
}
}
}
}
Každá hodnota v Composable je sledovatelná zpět ke klíči tokenu v IR. Nic není hardcódované — 16.dp pochází z spacing.16, 24.dp z spacing.24, Color(0xFF7F5CFE) z color.7f5cfe.
String refs — mapování stringResource
Každý textový uzel v IR nese stringRef s klíčem tečkové notace. Soubor strings.json mapuje klíče na zobrazované hodnoty a záložní hodnoty:
{
"home.title": { "value": "Good morning", "fallback": "Good morning" },
"home.card.label": { "value": "Today's summary", "fallback": "Summary" }
}
Tečková notace se mapuje na ID Android string resources s tečkami nahrazenými podtržítky: home.title → R.string.home_title. Pole fallback je to, co hardkódujete jako doslovný řetězec, pokud prostředek ještě v strings.xml neexistuje:
text = stringResource(R.string.home_title, "Good morning")
Řekněte agentovi, aby vždy používal pole fallback — ne prázdný řetězec — aby byla obrazovka čitelná během vývoje před naplněním strings.xml.
Absolutní pozicování
Uzly s kind: "absolute" přímo používají souřadnice Figmy. Tyto se objevují v designech s překrývajícími se prvky nebo prvky ukotvenými na konkrétních pozicích. Mapování na Compose používá Box jako rodiče a Modifier.offset na dětích:
// IR: { "kind": "absolute", "x": 24, "y": 80, "width": 120, "height": 40 }
Box(modifier = Modifier.fillMaxSize()) {
Box(
modifier = Modifier
.offset(x = 24.dp, y = 80.dp)
.size(width = 120.dp, height = 40.dp)
) {
// children
}
}
Absolutní pozicování je neobvyklé v dobře strukturovaných souborech Figmy (většina moderních souborů používá auto-layout). Když ho vidíte, zkontrolujte, zda záměr designu je skutečně absolutní nebo zda designér pouze neaplikoval omezení auto-layoutu — IR nemůže záměr odvodit.
Upřímné mezery
Balíček dobře pokrývá běžné případy. Několik věcí nepokrývá:
- Přechodové výplně. IR vydá varování, když narazí na přechod. Výplň pozadí uzlu je vynechána. Zanechte
// TODO: gradienta implementujte ho ručně. - Komplexní efekty. Stíny a rozostření nejsou v IR reprezentovány. Objevují se v upozorněních
_meta.json, pokud jsou přítomny. - Vektorové ikony. IR ukládá referenční ID pro uzly ikon, nikoli data cest. Ikonu budete muset samostatně rozeznat na skutečný drawable nebo ikonu compose.
- Vnořené komponenty. IR zahrnuje
componentIdna uzlech instancí.components/inventory.jsonmapuje ID na jména. Implementujte komponentu samostatně a odkazujte na ni jménem v nadřazeném Composable.
Tyto mezery jsou explicitní — zobrazují se v upozorněních _meta.json a CONTEXT.md. Agent jimi tiše neuhádá.
Exportujte kontextový balíček z hlavní aplikace figmascope.dev, pak ho použijte s Claude Code nebo Cursor pro implementaci Composables přímo z IR. Žádné hádání ze screenshotů, žádné hardkódované hodnoty.