Communitygithub.com

MohamedRamadanSalah/figma-lens

Implementiere UI aus Figma-Designs pixelgenau mit figma-lens-Exporten (design/<frame>/spec.md, tokens.json, Screenshots, SVG-Icons) — ohne Figma-MCP oder Dev-Modus. Verwende dies immer, wenn der Benutzer darum bittet, einen Bildschirm oder eine Komponente „aus Figma“ zu erstellen, zu implementieren, anzupassen oder zu reparieren, einen design/-Ordner oder figma-lens-Export erwähnt oder Flutter- oder Web-Code (HTML/CSS/React/Tailwind) wünscht, der zu einem Figma-Frame passt.

Was ist figma-lens?

figma-lens ist ein Skill, der es AI-Coding-Agents wie Claude Code, Cursor und Codex ermöglicht, UI pixelgenau aus Figma-Designs zu implementieren, ohne dass eine Figma-MCP-Integration oder der Dev-Modus erforderlich ist. Er nutzt einen lokalen Bridge-Server und ein Figma-Plugin: Der Benutzer wählt Frames in Figma Desktop aus und exportiert sie über das Plugin; der Bridge-Server schreibt dann für jeden Frame einen strukturierten Ordner mit einer Spezifikation (spec.md), Token-Definitionen (tokens.json), einem Vollbild-Rendering ([email protected]), Abschnitts-Crops, SVG-Icons und Assets. Der Workflow ist streng: Zuerst wird die Spezifikation vollständig gelesen, dann werden die Bilder zur visuellen Überprüfung herangezogen, und schließlich wird die Benutzeroberfläche von oben nach unten gemäß der Layer-Struktur erstellt, wobei vorhandene Komponenten und Token aus der Projekt-Codebasis über eine Komponenten-Map (figma-lens.map.json) wiederverwendet werden. Eine integrierte Vergleichs- und Korrekturschleife generiert Side-by-Side-Diff-Berichte — der Agent erstellt den Bildschirm, führt einen Screenshot-Vergleich mit figma-lens check durch, liest den Mismatch-Report und korrigiert die Code-Unterschiede iterativ, bis die Abweichung ≤3 % beträgt. Dieser Skill ist ideal für Entwickler, die Flutter- (Material, Cupertino) oder Web-Frontends (React, HTML/CSS, Tailwind) erstellen, die exakt mit Figma-Designs übereinstimmen müssen, und er stellt sicher, dass Werte aus der Spezifikation und nicht durch manuelle Pixelvermessung ermittelt werden.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/MohamedRamadanSalah/figma-lens/tree/HEAD/skill/figma-lens

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

figma-lens: Benutzerschnittstellen bauen, die zu Figma passen

figma-lens ist ein Figma-Plugin plus eine lokale Brücke. Der Benutzer wählt Frames in Figma Desktop aus und klickt auf Export to Claude. Die Brücke schreibt einen Ordner pro Frame:

design/
  INDEX.md              ← Liste aller exportierten Frames (hier starten)
  <frame>/
    spec.md             ← ZUERST LESEN: kompakte Layer-Struktur mit genauen Werten
    spec.json           ← vollständige Daten (+ pro-Layer CSS von Figma) wenn spec.md nicht ausreicht
    tokens.json         ← Variablen (alle Modi), Stile, Nutzungszahlen von Rohwerten
    [email protected]       ← vollständige Darstellung (standardmäßig 2x)
    sections/NN-name.png← Ausschnitte der obersten Blöcke in voller Auflösung
    assets/*.svg        ← Icons/Vektorgrafiken, einsatzbereit
    images/*            ← Original-Bitmaps, die als Bildfüllungen verwendet werden
    compare/            ← geschrieben von `figma-lens check` (report.md, side-by-side.png, diff.png)
figma-lens.map.json     ← (Projektwurzel) Figma-Komponente/Token → echter Code in diesem Projekt

Der Befehl figma-lens ist das CLI aus dem figma-lens-Repository (npm link dort macht es global verfügbar; ansonsten führen Sie node <figma-lens>/bin/figma-lens.js … aus). Führen Sie figma-lens help für alle Befehle aus.

Wenn es noch keinen Export gibt

  1. Starten Sie die Brücke für das Projekt des Benutzers und lassen Sie sie (im Hintergrund) laufen: figma-lens bridge --out <projekt>/design.
  2. Bitten Sie den Benutzer, den/die Frame(s) in Figma Desktop auszuwählen → Plugins → Entwicklung → Figma Lens → Export to Claude.
  3. Lesen Sie design/INDEX.md, um zu bestätigen, dass sie angekommen sind.

Raten Sie nie ein Design aus einer Beschreibung, wenn ein Export möglich ist. Fragen Sie nach dem Export.

Arbeitsablauf

  1. Lesen Sie spec.md vollständig (es ist klein). Notieren Sie sich die Framegröße, die Layout-Struktur, die Variablen und Stile sowie die Assets.
  2. Betrachten Sie die Bilder. Lesen Sie sections/*.png nacheinander für Details. Verwenden Sie [email protected] nur für das Gesamtbild, da große Bilder beim Anzeigen verkleinert werden. Werte stammen immer aus der Spezifikation, niemals durch Messen von Pixeln.
  3. Verwenden Sie die Komponentenkarte (siehe „Komponentenkarte" unten). Jedes ⇒ USE … in spec.md ist verbindlich: verwenden Sie dieses Widget/Komponente und seine Eigenschaftszuordnung sowie zugeordnete Token ((color/primary ⇒ AppColors.primary)) anstelle von Rohwerten. Für Elemente, die als (not in map) markiert sind, durchsuchen Sie die Codebasis nach dem vorhandenen Theme und den vorhandenen Widgets (Flutter ThemeData, AppColors, TextTheme, Abstandskonstanten, lib/widgets; Web CSS-Variablen, Tailwind-Konfiguration, src/components). Verwenden Sie Rohwerte nur, wenn kein Token existiert, und teilen Sie dem Benutzer mit, welche Sie hinzugefügt haben.
  4. Wiederverwenden von Komponenten. Ein Layer, der als component Button {Type=Primary} markiert ist, sollte das vorhandene Button-Widget oder die vorhandene Komponente des Projekts mit passenden Eigenschaften verwenden. Bauen Sie eine neue nur, wenn keine existiert, machen Sie sie wiederverwendbar und fügen Sie sie der Karte hinzu.
  5. Bauen Sie von oben nach unten, folgen Sie der Struktur. Automatisches Layout wird auf Row/Column/flex abgebildet (Tabellen unten). Nur @x,y-Layer (kein automatisches Layout oder absolute) benötigen Stack/Positioned oder absolute Positionierung.
  6. Verwenden Sie die exportierten Dateien. Legen Sie assets/*.svg und images/* in den Asset-Ordner des Projekts und referenzieren Sie sie. Zeichnen Sie niemals Icons neu und ersetzen Sie niemals ein Icon-Set durch ein anderes.
  7. Kopieren Sie Text genau aus "…" in spec.md, einschließlich Groß-/Kleinschreibung, Interpunktion und arabischen/RTL-Strings. Text mit mehreren run-Zeilen benötigt Rich-Text (TextSpan / verschachtelte Spans).
  8. Überprüfen Sie mit der Vergleichs- und Korrekturschleife (unten). Erklären Sie einen Bildschirm nicht als fertig, indem Sie den Code lesen; beweisen Sie es mit einem Screenshot-Diff.

Vergleichs- und Korrekturschleife

Nachdem Sie einen Bildschirm gebaut haben, vergleichen Sie das tatsächliche Ergebnis mit Figma und korrigieren Sie, was abweicht:

  1. Führen Sie den Build aus, der diesen Bildschirm anzeigt:
    • Web: Starten Sie den Dev-Server und öffnen Sie die Route.
    • Flutter web: flutter run -d web-server --web-port 8080, dann verwenden Sie diese URL.
    • Flutter Android: Führen Sie die App auf einem Emulator/Gerät aus und navigieren Sie zum Bildschirm.
  2. Überprüfen Sie ihn:
    • Web / Flutter web: figma-lens check --design design/<frame> --url http://localhost:<port>/<route> (der Viewport wird automatisch auf die Größe des Frames und den Maßstab eingestellt).
    • Android: figma-lens check --design design/<frame> --adb --crop-top <statusleiste px> [--crop-bottom <nav-bar px>] (Statusleiste ≈ 24–48 dp × Gerätedichte; zuschneiden, sodass nur der App-Inhalt verglichen wird).
  3. Lesen Sie design/<frame>/compare/report.md (Abweichung in %, die größten unterschiedlichen Bereiche und die Figma-Layer-IDs in jedem) und sehen Sie sich compare/side-by-side.png an (Figma | Build | Diff, rot = unterschiedlich).
  4. Korrigieren Sie von oben nach unten: zuerst Höhen- oder Abstandsunterschiede (sie verschieben alles darunter), dann Größen, Farben, Typografie, Radien, Schatten. Schlagen Sie jede aufgeführte Layer-ID in spec.md nach, um die genauen Werte zu erhalten.
  5. Führen Sie die Prüfung erneut aus. Der Bericht zeigt den vorherigen Score, sodass Sie den Fortschritt sehen können.
  6. Stoppen Sie, wenn die Abweichung ≤ 3% beträgt (Text-Anti-Aliasing erreicht nie 0) oder wenn zwei aufeinanderfolgende Läufe keine Verbesserung mehr zeigen. Melden Sie dann den endgültigen Score und alles, was Sie nicht angleichen konnten, sowie den Grund (fehlende Schriftart, plattformbedingtes Rendering, dynamische Daten).

Regeln: Korrigieren Sie den echten Code, manipulieren Sie niemals den Diff (keine Screenshots oder Bilder des Designs innerhalb der App). Verwenden Sie beim Überprüfen dieselben Daten/denselben Text wie das Design (ggf. Mock-Daten), sonst dominieren Textunterschiede den Score.

Komponentenkarte

figma-lens.map.json (Projektwurzel) bildet Figma-Komponenten und -Token auf den Code dieses Projekts ab:

{
  "components": {
    "Button": { "flutter": "lib/widgets/app_button.dart#AppButton", "web": "src/components/Button.tsx#Button", "props": { "Label": "label", "Type": "variant" } },
    "Icon/*": "SvgPicture.asset('assets/icons/<name>.svg')"
  },
  "tokens": { "color/primary": { "flutter": "AppColors.primary", "web": "var(--color-primary)" } }
}
  • Noch keine Karte vorhanden → führen Sie figma-lens map --design design aus. Es fügt jede Komponente und jeden Token aus den Exporten mit leeren Werten ("") hinzu.
  • Füllen Sie sie selbst aus: Durchsuchen Sie die Codebasis nach jeder Komponente (nach Namen, Aussehen, Eigenschaften) und jedem Token-Wert; schreiben Sie path#Symbol (oder einen Ausdruck). Lassen Sie "" nur, wenn noch nichts existiert. "Prefix/*" trifft auf eine ganze Familie zu (Icons).
  • Nachdem Sie die Karte bearbeitet haben, führen Sie figma-lens render design/<frame> aus, damit spec.md die ⇒ USE-Pfeile anzeigt. Die Brücke wendet die Karte auch bei jedem neuen Export an.
  • Wenn Sie ein neues wiederverwendbares Widget für eine nicht zugeordnete Komponente erstellen, fügen Sie es der Karte hinzu.

Lesen von spec.md

  • Einheiten sind Design-Pixel, die CSS-Pixel und Flutter-logischen Pixeln entsprechen. Multiplizieren Sie niemals mit dem Screenshot-Maßstab.
  • row|column gap G pad t,r,b,l main:X cross:Y ist automatisches Layout. pad 16 bedeutet, dass alle vier Seiten 16 sind. gap auto bedeutet space-between.
  • w:FILL h:HUG gibt die Größenanpassung auf jeder Achse an: FIXED (angezeigte genaue Größe), HUG (Inhalt umschließen) oder FILL (verfügbaren Platz einnehmen).
  • @x,y ist die Position innerhalb des Elternelements. absolute bedeutet ein absolut positioniertes Kind innerhalb eines automatischen Layouts. pin H/V gibt Randbedingungen an (MIN = links/oben, MAX = rechts/unten, STRETCH = beide, CENTER, SCALE).
  • bg A + B listet Farben von unten nach oben auf. (name) ist eine Figma-Variable und [style name] ist ein Figma-Stil.
  • Farben sind #RRGGBB oder #RRGGBBAA (Alpha am Ende).
  • Text verwendet das Format "Zeichen" · Familie Stil (Gewicht) Größe/ZeilenHöhe Farbe. ZeilenHöhe ist px, % oder auto. ls ist der Buchstabenabstand in px oder in % der Schriftgröße.
  • radius 12 setzt jede Ecke. radius tl,tr,br,bl setzt jede Ecke einzeln. smoothing ist abgerundete Ecken im iOS-Stil; approximieren Sie es, oder ignorieren Sie es in Flutter, es sei denn, ein Squircle-Paket wird verwendet.
  • drop-shadow x,y blur B spread S color, inner-shadow, layer-blur R, background-blur R.
  • → assets/x.svg bedeutet, dass der Layer ein Icon ist. Verwenden Sie das SVG in der angegebenen Größe.
  • vars{itemSpacing=space/md} bedeutet, dass die Layereigenschaft an diese Variable gebunden ist. Verwenden Sie den Token.

Flutter-Zuordnung

FigmaFlutter
column / rowColumn / Row (verwenden Sie spacing: G auf Flutter ≥ 3.27, sonst SizedBox-Lücken)
wrap, rowGap RWrap(spacing: G, runSpacing: R)
pad t,r,b,lPadding(padding: EdgeInsets.fromLTRB(l, t, r, b)). Achten Sie auf die Reihenfolge.
main MIN / CENTER / MAX / SPACE_BETWEENMainAxisAlignment.start / center / end / spaceBetween
cross MIN / CENTER / MAX / BASELINECrossAxisAlignment.start / center / end / baseline (baseline benötigt textBaseline)
HUG auf HauptachsemainAxisSize: MainAxisSize.min
FILL auf Hauptachse des ElternteilsExpanded (oder Flexible); grow N setzt flex: N
FILL auf Querachse des ElternteilsCrossAxisAlignment.stretch auf dem Elternteil, oder SizedBox(width: double.infinity)
FIXED w×hSizedBox(width: w, height: h)
@x,y / absoluteStack + Positioned(left: x, top: y); verwenden Sie pin für rechts/unten
bg solidBoxDecoration(color: Color(0xAARRGGBB)). Verschieben Sie Alpha nach vorne: #11223380 → 0x80112233.
gradient-linear von/nachLinearGradient(begin: Alignment(fx*2-1, fy*2-1), end: Alignment(tx*2-1, ty*2-1), colors, stops) unter Verwendung von from/to in spec.json
radiusBorderRadius.circular(r) oder BorderRadius.only(...)
border W color insideBorder.all(width: W, color: …) (inside ist Flutters Standard; center/outside benötigen strokeAlign)
drop-shadow x,y blur B spread SBoxShadow(offset: Offset(x, y), blurRadius: B, spreadRadius: S, color: …)
background-blur RClipRRect + BackdropFilter(filter: ImageFilter.blur(sigmaX: R/2, sigmaY: R/2))
opacityOpacity (oder Farb-Alpha für Farben)
text size/lineHeightTextStyle(fontSize: size, height: lineHeight / size). Für %: height: pct/100. Setzen Sie leadingDistribution: TextLeadingDistribution.even, um Figmas vertikaler Zentrierung zu entsprechen.
weight 600FontWeight.w600
ls px / ls %letterSpacing: px / letterSpacing: size * pct / 100
ellipsis maxLines NmaxLines: N, overflow: TextOverflow.ellipsis
align CENTERtextAlign: TextAlign.center. Verwenden Sie für RTL-Bildschirme TextAlign.start und EdgeInsetsDirectional.
assets/x.svgSvgPicture.asset('assets/…/x.svg', width:, height:) (flutter_svg)
image fill FILL / FITImage.asset(fit: BoxFit.cover / BoxFit.contain)

Web (CSS / Tailwind / React)-Zuordnung

FigmaCSS
column / rowdisplay:flex; flex-direction: column / row; gap: Gpx
wrap, rowGap Rflex-wrap: wrap; column-gap: G; row-gap: R
pad t,r,b,lpadding: t r b l (gleiche Reihenfolge wie CSS)
main MIN / CENTER / MAX / SPACE_BETWEENjustify-content: flex-start / center / flex-end / space-between
cross MIN / CENTER / MAX / BASELINEalign-items: flex-start / center / flex-end / baseline
HUGwidth/height: fit-content (oder einfach auto)
FILL (Hauptachse)flex: 1 1 0; min-width: 0
FILL (Querachse)align-self: stretch
FIXEDwidth: Wpx; height: Hpx; flex-shrink: 0
@x,y / absoluteparent position: relative; child position:absolute; left:x; top:y (verwenden Sie pin für rechts/unten)
colors #RRGGBBAAgültiges CSS wie es ist
gradient-linear Ndeglinear-gradient(Ndeg, c1 p1%, c2 p2%)
drop-shadowbox-shadow: x y B S color (inner-shadow fügt inset hinzu)
layer-blur / background-blur Rfilter: blur(R/2 px) / backdrop-filter: blur(R/2 px)
textfont: weight size/lineHeight family; letter-spacing (ls % → pct/100 em)
ellipsis maxLines Ndisplay:-webkit-box; -webkit-line-clamp:N; -webkit-box-orient:vertical; overflow:hidden
assets/x.svg<img src> oder inline SVG; behalten Sie die exportierte Größe bei

spec.json enthält auch das von Figma generierte CSS (css) für die meisten Layer. Verwenden Sie es, um die CSS-Werte gegenzuprüfen; Token und Layout-Struktur stammen immer noch aus der obigen Struktur.

Regeln

  • Spezifikationswerte haben Vorrang vor dem, was Sie im Bild sehen. Bei Konflikten vertrauen Sie der Spezifikation und erwähnen Sie den Konflikt.
  • Runden oder „verbessern" Sie keine Werte (14 bleibt 14, nicht 16), es sei denn, der Benutzer fordert eine Normalisierung auf Token an.
  • Ausgeblendete Layer werden nicht exportiert. Erfinden Sie keine Zustände (Hover, Fehler, leer), die nicht im Export enthalten sind; fragen Sie nach diesen Frames.
  • Melden Sie fehlende Schriftarten. Wenn die Schriftfamilie nicht im Projekt gebündelt ist, sagen Sie dies und teilen Sie dem Benutzer mit, was hinzugefügt werden muss (pubspec fonts / @font-face).
  • Fragen Sie für mehrere Breakpoints oder Zustände den Benutzer, jeden Frame zu exportieren. Jeder wird zu einem eigenen Ordner.

Verwandte Skills