Skip to content

Commit 30ea8e1

Browse files
authored
fix(ui): blocks field not respecting width styles in row layouts (#13502)
### What? This PR applies `mergeFieldStyles` to the `BlocksField` component, ensuring that custom admin styles such as `width` are correctly respected when Blocks fields are placed inside row layouts. ### Why? Previously, Blocks fields did not inherit or apply their `admin.width` (or other merged field styles). For example, when placing two Blocks fields side by side inside a row with `width: '50%'`, the widths were ignored, causing layout issues. ### How? - Imported and used `mergeFieldStyles` within `BlocksField`. - Applied the merged styles to the root `<div>` via the `style` prop, consistent with how other field components (like `TextField`) handle styles. Fixes #13498
1 parent f9bbca8 commit 30ea8e1

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

packages/ui/src/fields/Blocks/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import './index.scss'
3535
import { FieldDescription } from '../FieldDescription/index.js'
3636
import { FieldError } from '../FieldError/index.js'
3737
import { FieldLabel } from '../FieldLabel/index.js'
38+
import { mergeFieldStyles } from '../mergeFieldStyles.js'
3839
import { fieldBaseClass } from '../shared/index.js'
3940
import { BlockRow } from './BlockRow.js'
4041
import { BlocksDrawer } from './BlocksDrawer/index.js'
@@ -45,6 +46,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
4546
const { i18n, t } = useTranslation()
4647

4748
const {
49+
field,
4850
field: {
4951
name,
5052
type,
@@ -294,6 +296,8 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
294296
const showMinRows = rows.length < minRows || (required && rows.length === 0)
295297
const showRequired = readOnly && rows.length === 0
296298

299+
const styles = useMemo(() => mergeFieldStyles(field), [field])
300+
297301
return (
298302
<div
299303
className={[
@@ -305,6 +309,7 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
305309
.filter(Boolean)
306310
.join(' ')}
307311
id={`field-${path?.replace(/\./g, '__')}`}
312+
style={styles}
308313
>
309314
{showError && (
310315
<RenderCustomComponent

test/fields/collections/Row/e2e.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,41 @@ describe('Row', () => {
205205
expect(fieldABox.height).toEqual(fieldBBox.height)
206206
}).toPass()
207207
})
208+
209+
test('should respect admin.width for Blocks fields inside a row', async () => {
210+
await page.goto(url.create)
211+
212+
// Target the Blocks field wrappers
213+
const left = page.locator('#field-leftColumn')
214+
const right = page.locator('#field-rightColumn')
215+
216+
await expect(left).toBeVisible()
217+
await expect(right).toBeVisible()
218+
219+
// 1) CSS variable is applied (via mergeFieldStyles)
220+
const leftVar = await left.evaluate((el) =>
221+
getComputedStyle(el).getPropertyValue('--field-width').trim(),
222+
)
223+
const rightVar = await right.evaluate((el) =>
224+
getComputedStyle(el).getPropertyValue('--field-width').trim(),
225+
)
226+
227+
expect(leftVar).toBe('50%')
228+
expect(rightVar).toBe('50%')
229+
230+
// Also assert inline style contains the var (robust to other inline styles)
231+
await expect(left).toHaveAttribute('style', /--field-width:\s*50%/)
232+
await expect(right).toHaveAttribute('style', /--field-width:\s*50%/)
233+
234+
// 2) Layout reflects the widths (same row, equal widths)
235+
const leftBox = await left.boundingBox()
236+
const rightBox = await right.boundingBox()
237+
238+
await expect(() => {
239+
// Same row
240+
expect(Math.round(leftBox.y)).toEqual(Math.round(rightBox.y))
241+
// Equal width (tolerate sub-pixel differences)
242+
expect(Math.round(leftBox.width)).toEqual(Math.round(rightBox.width))
243+
}).toPass()
244+
})
208245
})

test/fields/collections/Row/index.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,47 @@ const RowFields: CollectionConfig = {
137137
},
138138
],
139139
},
140+
{
141+
type: 'row',
142+
fields: [
143+
{
144+
name: 'leftColumn',
145+
type: 'blocks',
146+
blocks: [
147+
{
148+
slug: 'leftTextBlock',
149+
fields: [
150+
{
151+
name: 'leftText',
152+
type: 'text',
153+
},
154+
],
155+
},
156+
],
157+
admin: {
158+
width: '50%',
159+
},
160+
},
161+
{
162+
name: 'rightColumn',
163+
type: 'blocks',
164+
blocks: [
165+
{
166+
slug: 'rightTextBlock',
167+
fields: [
168+
{
169+
name: 'rightText',
170+
type: 'text',
171+
},
172+
],
173+
},
174+
],
175+
admin: {
176+
width: '50%',
177+
},
178+
},
179+
],
180+
},
140181
],
141182
}
142183

test/fields/payload-types.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,22 @@ export interface RowField {
11291129
no_set_width_within_row_b?: string | null;
11301130
no_set_width_within_row_c?: string | null;
11311131
field_20_percent_width_within_row_d?: string | null;
1132+
leftColumn?:
1133+
| {
1134+
leftText?: string | null;
1135+
id?: string | null;
1136+
blockName?: string | null;
1137+
blockType: 'leftTextBlock';
1138+
}[]
1139+
| null;
1140+
rightColumn?:
1141+
| {
1142+
rightText?: string | null;
1143+
id?: string | null;
1144+
blockName?: string | null;
1145+
blockType: 'rightTextBlock';
1146+
}[]
1147+
| null;
11321148
updatedAt: string;
11331149
createdAt: string;
11341150
}
@@ -2760,6 +2776,28 @@ export interface RowFieldsSelect<T extends boolean = true> {
27602776
no_set_width_within_row_b?: T;
27612777
no_set_width_within_row_c?: T;
27622778
field_20_percent_width_within_row_d?: T;
2779+
leftColumn?:
2780+
| T
2781+
| {
2782+
leftTextBlock?:
2783+
| T
2784+
| {
2785+
leftText?: T;
2786+
id?: T;
2787+
blockName?: T;
2788+
};
2789+
};
2790+
rightColumn?:
2791+
| T
2792+
| {
2793+
rightTextBlock?:
2794+
| T
2795+
| {
2796+
rightText?: T;
2797+
id?: T;
2798+
blockName?: T;
2799+
};
2800+
};
27632801
updatedAt?: T;
27642802
createdAt?: T;
27652803
}

0 commit comments

Comments
 (0)