Automattic / Automattic/blocks-engine
Figma transformer: responsive emission — consume sibling-groups → emit @media
- Dominant language
- PHP
- Stars
- 14
- Forks
- 2
- Avg merge
- 2h 10m
- Merged PRs (30d)
- 561
Description
## Problem
The Figma transformer renders a single fixed-width canvas, not a responsive website. The root wrapper is `.figma-root{position:relative;min-width:100%;width:max-content}` (fixed canvas width → horizontal scroll on narrow viewports) and there are **zero `@media` queries package-wide**. Auto-layout frames map to real flexbox and FILL/HUG sizing is honored, so output is faithful at the design's native width — but it does not reflow.
To date, 35 merged figma PRs are all single-width fidelity/diagnostics work. Responsive **emission** has never been attempted.
## What exists already
Detection of responsive frame sets now lands in `ScenegraphFrameInspector` (PR landing the `cook/figma-selection-responsive` branch):
- `deviceHint()` — classifies a frame `mobile`/`tablet`/`desktop` by name regex + width thresholds (<700 / 700–1100 / ≥1100).
- `siblingGroupKey()` + `responsiveSiblings()` — groups frames that represent one page at multiple widths.
- `normalizedPageName()` / `nameSimilarity()` — strip `desktop`/`mobile`/`copy`/`v2`/`variant` suffixes so siblings match by base name.
This is **detection only**. `device_hint` / `sibling_group_key` / `responsive_siblings` are consumed by nothing — neither `ScenegraphPagePlanner` nor `StaticHtmlEmitter` reads them.
## Scope
1. **PagePlanner** — collapse a responsive sibling-group into a single page with N breakpoint variants (instead of one page per frame).
2. **StaticHtmlEmitter** — diff per-breakpoint styles and emit `@media` blocks; share the existing flex/FILL/HUG machinery across breakpoints rather than re-deriving layout.
3. **Fluid root** — replace `width:max-content` with a centered `max-width` container for FILL roots; clear the `fixed_root_width_count` diagnostic smell.
4. **Per-breakpoint parity** — extend the parity contract so each breakpoint is verified against its corresponding source frame. Responsiveness is unfalsifiable while parity is measured at a single viewport.
## Acceptance
- A Figma file with desktop/tablet/mobile frames of the same page produces one HTML page with `@media` breakpoints that match each source frame.
- Parity report records a pass/fail per breakpoint against its source frame.
Contributor guide
Research direction
Start by tracing the existing detection in ScenegraphFrameInspector into the currently uninvolved ScenegraphPagePlanner and StaticHtmlEmitter. Read the parity contract and its single-viewport measurement to determine how breakpoint-specific source frames are represented. Done means one page from a responsive sibling-group, matching @media output for desktop/tablet/mobile, a fluid FILL root, and a pass/fail parity result per breakpoint.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- frontend, testing, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100