fix(ui): array fields not respecting width styles in row layouts (#13986)

### What?

This PR applies `mergeFieldStyles` to the `ArrayFieldComponent`
component, ensuring that custom admin styles such as `width` are
correctly respected when Array fields are placed inside row layouts.

### Why?

Previously, Array fields did not inherit or apply their `admin.width`
(or other merged field styles). For example, when placing two array
fields side by side inside a row with `width: '50%'`, the widths were
ignored, causing layout issues.

### How?

- Imported and used `mergeFieldStyles` within `ArrayFieldComponent`.
- Applied the merged styles to the root `<div>` via the `style` prop,
consistent with how other field components (like `TextField`) handle
styles.

Fixes #13973 


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211511898438801
This commit is contained in:
Patrik
2025-10-01 13:15:30 -04:00
committed by GitHub
parent 54b6f15392
commit accd95ec8a
4 changed files with 104 additions and 3 deletions

View File

@@ -224,8 +224,49 @@ describe('Row', () => {
getComputedStyle(el).getPropertyValue('--field-width').trim(),
)
expect(leftVar).toBe('50%')
expect(rightVar).toBe('50%')
await expect(() => {
expect(leftVar).toBe('50%')
expect(rightVar).toBe('50%')
}).toPass()
// Also assert inline style contains the var (robust to other inline styles)
await expect(left).toHaveAttribute('style', /--field-width:\s*50%/)
await expect(right).toHaveAttribute('style', /--field-width:\s*50%/)
// 2) Layout reflects the widths (same row, equal widths)
const leftBox = await left.boundingBox()
const rightBox = await right.boundingBox()
await expect(() => {
// Same row
expect(Math.round(leftBox.y)).toEqual(Math.round(rightBox.y))
// Equal width (tolerate sub-pixel differences)
expect(Math.round(leftBox.width)).toEqual(Math.round(rightBox.width))
}).toPass()
})
test('should respect admin.width for array fields inside a row', async () => {
await page.goto(url.create)
// Target the Array field wrappers
const left = page.locator('#field-arrayLeftColumn')
const right = page.locator('#field-arrayRightColumn')
await expect(left).toBeVisible()
await expect(right).toBeVisible()
// 1) CSS variable is applied (via mergeFieldStyles)
const leftVar = await left.evaluate((el) =>
getComputedStyle(el).getPropertyValue('--field-width').trim(),
)
const rightVar = await right.evaluate((el) =>
getComputedStyle(el).getPropertyValue('--field-width').trim(),
)
await expect(() => {
expect(leftVar).toBe('50%')
expect(rightVar).toBe('50%')
}).toPass()
// Also assert inline style contains the var (robust to other inline styles)
await expect(left).toHaveAttribute('style', /--field-width:\s*50%/)

View File

@@ -178,6 +178,37 @@ const RowFields: CollectionConfig = {
},
],
},
{
type: 'row',
fields: [
{
name: 'arrayLeftColumn',
type: 'array',
admin: {
width: '50%',
},
fields: [
{
name: 'leftArrayChild',
type: 'text',
},
],
},
{
name: 'arrayRightColumn',
type: 'array',
fields: [
{
name: 'rightArrayChild',
type: 'text',
},
],
admin: {
width: '50%',
},
},
],
},
],
}

View File

@@ -1194,6 +1194,18 @@ export interface RowField {
blockType: 'rightTextBlock';
}[]
| null;
arrayLeftColumn?:
| {
leftArrayChild?: string | null;
id?: string | null;
}[]
| null;
arrayRightColumn?:
| {
rightArrayChild?: string | null;
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
}
@@ -2904,6 +2916,18 @@ export interface RowFieldsSelect<T extends boolean = true> {
blockName?: T;
};
};
arrayLeftColumn?:
| T
| {
leftArrayChild?: T;
id?: T;
};
arrayRightColumn?:
| T
| {
rightArrayChild?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
}