Skip to content

Commit e5db5e6

Browse files
committed
Update form.tsx
1 parent a26decd commit e5db5e6

1 file changed

Lines changed: 70 additions & 4 deletions

File tree

  • packages/components/src/renderers/form

packages/components/src/renderers/form/form.tsx

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,77 @@ ComponentRegistry.register('form',
334334
// Resolve the component type: prefer widget override, fallback to field type
335335
const resolvedType = widget || type;
336336

337-
// colSpan classes for grid layout
337+
// colSpan classes for grid layout.
338+
//
339+
// When the container uses container-query-based grid classes
340+
// (e.g. `@md:grid-cols-2`), the grid's base is `grid-cols-1`
341+
// on narrow containers. Applying a bare `col-span-2` in that
342+
// state causes CSS grid to synthesize an implicit 2nd column
343+
// track, distorting column widths. We must mirror the same
344+
// container-query prefix on the col-span utilities so they
345+
// only engage once the grid is actually multi-column.
346+
// The effective container is whatever wraps the fields: either
347+
// `fieldContainerClass` (overrides, typically container-query based)
348+
// or the locally-computed `gridClass` (viewport-based).
349+
const containerClass = schema.fieldContainerClass || gridClass;
350+
// Match both container-query (`@md:`) and viewport (`md:`) prefixes.
351+
// Return an explicit, statically-detectable class so Tailwind JIT
352+
// can scan and include it.
353+
const pickSpanClass = (targetCols: number): string => {
354+
const re = /(@)?(sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl):grid-cols-(\d+)/g;
355+
const matches = Array.from(containerClass.matchAll(re)).map(m => ({
356+
at: m[1] || '',
357+
bp: m[2],
358+
cols: Number(m[3]),
359+
}));
360+
if (!matches.length) {
361+
// No responsive/container prefix found — bare class is safe
362+
// because the grid is already multi-column at all widths.
363+
if (targetCols === 2) return 'col-span-2';
364+
if (targetCols === 3) return 'col-span-3';
365+
return 'col-span-4';
366+
}
367+
const hit = matches.find(m => m.cols >= targetCols) || matches[matches.length - 1];
368+
const key = `${hit.at}${hit.bp}:${targetCols}`;
369+
// Explicit literal map so Tailwind JIT discovers these classes.
370+
const table: Record<string, string> = {
371+
'@sm:2': '@sm:col-span-2',
372+
'@md:2': '@md:col-span-2',
373+
'@lg:2': '@lg:col-span-2',
374+
'@xl:2': '@xl:col-span-2',
375+
'@2xl:2': '@2xl:col-span-2',
376+
'@sm:3': '@sm:col-span-3',
377+
'@md:3': '@md:col-span-3',
378+
'@lg:3': '@lg:col-span-3',
379+
'@xl:3': '@xl:col-span-3',
380+
'@2xl:3': '@2xl:col-span-3',
381+
'@4xl:3': '@4xl:col-span-3',
382+
'@sm:4': '@sm:col-span-4',
383+
'@md:4': '@md:col-span-4',
384+
'@lg:4': '@lg:col-span-4',
385+
'@xl:4': '@xl:col-span-4',
386+
'@2xl:4': '@2xl:col-span-4',
387+
'@4xl:4': '@4xl:col-span-4',
388+
'sm:2': 'sm:col-span-2',
389+
'md:2': 'md:col-span-2',
390+
'lg:2': 'lg:col-span-2',
391+
'xl:2': 'xl:col-span-2',
392+
'sm:3': 'sm:col-span-3',
393+
'md:3': 'md:col-span-3',
394+
'lg:3': 'lg:col-span-3',
395+
'xl:3': 'xl:col-span-3',
396+
'sm:4': 'sm:col-span-4',
397+
'md:4': 'md:col-span-4',
398+
'lg:4': 'lg:col-span-4',
399+
'xl:4': 'xl:col-span-4',
400+
};
401+
return table[key] || (targetCols === 2 ? 'col-span-2' : targetCols === 3 ? 'col-span-3' : 'col-span-4');
402+
};
403+
338404
const colSpanClass = colSpan && colSpan > 1
339-
? colSpan === 2 ? 'col-span-2'
340-
: colSpan === 3 ? 'col-span-3'
341-
: colSpan >= 4 ? 'col-span-4'
405+
? colSpan === 2 ? pickSpanClass(2)
406+
: colSpan === 3 ? pickSpanClass(3)
407+
: colSpan >= 4 ? pickSpanClass(4)
342408
: ''
343409
: '';
344410

0 commit comments

Comments
 (0)