Skip to content

Commit f90ce16

Browse files
fix(Form): fix column layout for FormGroups (#5824)
1 parent 5057273 commit f90ce16

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

packages/main/src/components/Form/index.tsx

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,13 @@ const Form = forwardRef<HTMLFormElement, FormPropTypes>((props, ref) => {
219219
let nextRowIndex = (titleText ? 2 : 1) + rowsPerFormItem - 1;
220220
const rowsWithGroup = {};
221221

222-
const columnsWithItems: ItemInfo[][] = [];
222+
const columnsWithItems: Array<ItemInfo[]> = [];
223223
const rowsPerColumn = Math.ceil(items.size / currentNumberOfColumns);
224224

225225
const allItemsArray = Array.from(items.entries());
226226
const onlyFormItems = allItemsArray.every(([, item]) => item.type === 'formItem');
227+
const onlyFormGroups = allItemsArray.every(([, item]) => item.type === 'formGroup');
228+
const columnsToFill = Math.max(0, currentNumberOfColumns - allItemsArray.length);
227229

228230
allItemsArray.forEach(([id, item], idx) => {
229231
// when only FormItems are used, the Form should build up from top to bottom, then left to right
@@ -246,6 +248,75 @@ const Form = forwardRef<HTMLFormElement, FormPropTypes>((props, ref) => {
246248
rowIndex += rowsPerFormItem;
247249
});
248250
});
251+
} else if (onlyFormGroups && columnsToFill > 0) {
252+
const columnsToBalance = [...columnsWithItems]
253+
.sort(([a], [b]) => b.formItemIds.size - a.formItemIds.size)
254+
.slice(0, columnsToFill);
255+
for (const column of columnsToBalance) {
256+
const currentColumnIndex = columnsWithItems.findIndex(([c]) => {
257+
return c.id === column.at(0).id;
258+
});
259+
const unbalancedFormItems: Set<string> = column.at(0).formItemIds;
260+
const movedFormItems = new Set([
261+
...Array.from(unbalancedFormItems).slice(Math.ceil(unbalancedFormItems.size / 2))
262+
]);
263+
columnsWithItems.splice(currentColumnIndex + 1, 0, [
264+
{
265+
id: `${column.at(0).id}-clone`,
266+
type: column.at(0).type,
267+
formItemIds: movedFormItems
268+
}
269+
]);
270+
movedFormItems.forEach((item) => {
271+
unbalancedFormItems.delete(item);
272+
});
273+
}
274+
275+
const isInitialRender = columnsWithItems.every((itemInfos) => itemInfos.every((i) => i.formItemIds.size === 0));
276+
columnsWithItems.forEach((el, index) => {
277+
const allGroupsEmpty = el.every((i) => i.formItemIds.size === 0);
278+
if (!isInitialRender && allGroupsEmpty) {
279+
columnsWithItems.splice(index, 1);
280+
}
281+
});
282+
283+
let localColumnIndex = 0;
284+
let rowIndex = (titleText ? 2 : 1) + rowsPerFormItem - 1;
285+
286+
columnsWithItems.forEach(([{ id, formItemIds }]) => {
287+
const columnIndex = localColumnIndex % currentNumberOfColumns;
288+
index++;
289+
rowsWithGroup[rowIndex] = true;
290+
formGroups.push({ id, index, columnIndex, rowIndex });
291+
let localRowIndex = 1;
292+
let localIndex = 1;
293+
294+
if (!formItemIds.size) {
295+
nextRowIndex++;
296+
}
297+
formItemIds.forEach((itemId, _, set) => {
298+
formItems.push({
299+
id: itemId,
300+
index,
301+
groupId: id,
302+
columnIndex,
303+
rowIndex: rowIndex + localRowIndex,
304+
lastGroupItem: set.size === localIndex
305+
});
306+
if (set.size === localIndex) {
307+
if (nextRowIndex < rowIndex + localRowIndex + rowsPerFormItem) {
308+
nextRowIndex = rowIndex + localRowIndex + rowsPerFormItem;
309+
}
310+
}
311+
localRowIndex += rowsPerFormItem;
312+
localIndex++;
313+
});
314+
315+
if ((localColumnIndex + 1) % currentNumberOfColumns === 0) {
316+
rowIndex = nextRowIndex;
317+
}
318+
localColumnIndex++;
319+
});
249320
} else {
250321
let localColumnIndex = 0;
251322
let rowIndex = (titleText ? 2 : 1) + rowsPerFormItem - 1;

0 commit comments

Comments
 (0)