@@ -219,11 +219,13 @@ const Form = forwardRef<HTMLFormElement, FormPropTypes>((props, ref) => {
219
219
let nextRowIndex = ( titleText ? 2 : 1 ) + rowsPerFormItem - 1 ;
220
220
const rowsWithGroup = { } ;
221
221
222
- const columnsWithItems : ItemInfo [ ] [ ] = [ ] ;
222
+ const columnsWithItems : Array < ItemInfo [ ] > = [ ] ;
223
223
const rowsPerColumn = Math . ceil ( items . size / currentNumberOfColumns ) ;
224
224
225
225
const allItemsArray = Array . from ( items . entries ( ) ) ;
226
226
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 ) ;
227
229
228
230
allItemsArray . forEach ( ( [ id , item ] , idx ) => {
229
231
// 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) => {
246
248
rowIndex += rowsPerFormItem ;
247
249
} ) ;
248
250
} ) ;
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
+ } ) ;
249
320
} else {
250
321
let localColumnIndex = 0 ;
251
322
let rowIndex = ( titleText ? 2 : 1 ) + rowsPerFormItem - 1 ;
0 commit comments