Figma handed me a size guide with size labels down the left and Chest, Hip, Dimension across the top. Centra Measurement Charts store the opposite. Repeater X is sizes (horizontalLabels). Repeater Y is measurements (verticalLabels). Cell values live at values[measurementIndex][sizeIndex]. Trying to rotate that with CSS grid hacks on a Next.js PDP is how you ship a chart that looks right in Chrome and lies in Safari.
The first ProductSizeGuideSheet was a raw Vaul Drawer: right edge on md+, bottom sheet on mobile, sticky header, scrollable table body, reduced-motion overlay. It worked. Then every other overlay on the storefront invented its own padding, width, and scroll region. The size guide was the canary.
Domain owns the axis flip. mapMeasurementTable walks each size index and builds a row whose cells are verticalLabels.map((_, measurementIndex) => values[measurementIndex][sizeIndex]). Empty tables get skipped. Unit comes from displayUnit. A GraphQL fragment on product details feeds the mapper. Optional sizeGuide on the page view keeps the sheet off products without chart data.
function mapMeasurementTable(chart: CentraMeasurementChart) {
return chart.horizontalLabels.map((size, sizeIndex) => ({
size,
cells: chart.verticalLabels.map((_, measurementIndex) => chart.values[measurementIndex]?.[sizeIndex] ?? ''),
unit: chart.displayUnit,
}));
}The shop mapper translates known column keys to i18n (Chest, Hip, Dimension) and passes unknown Centra labels through unchanged. Designers can add a new measurement in Centra without a deploy, and the column header still reads human.
Later the same sheet moved onto the shared Panel molecule (see the notify-me post). Size selector gained a size-guide trigger beside the chips. Header and scroll body stayed the same because the table was already in design axes.
Centra chart axes vs Figma size guide
Centra stores sizes on X and measurements on Y. Design wants size rows. Flip once in domain, not in CSS.
| Size | Chest | Hip | Dimension |
|---|---|---|---|
| XS | 84 cm | 90 cm | 62 cm |
| S | 88 cm | 94 cm | 64 cm |
| M | 92 cm | 98 cm | 66 cm |
| L | 98 cm | 104 cm | 68 cm |
mapMeasurementTable built this from values[measurementIndex][sizeIndex]. Ready for ProductSizeGuideSheet.
Switch between Centra shape and transposed UI. Same numbers, different contract. Only one belongs in JSX.
Do not fight the PIM table in CSS. Transpose once, then render what Figma asked for.
Happy coding! Sander