Skip to content

Commit 93999c0

Browse files
authored
fix[sdks]: centering items in columns (#3979)
## Description when we vertically center two individual elements we use `margin-top: auto`, `margin-bottom: auto` to keep the elements in the center. Turns out the builder-columns box doesn't respect height and shrinks to what’s required and height gets applied to the root div (as we don’t use noWrap true in case of columns). To fix this, we are adding `height: 100%` to make sure that we respect the root div's height (if provided) Jira https://builder-io.atlassian.net/browse/ENG-8386 _Screenshot_ If relevant, add a screenshot or two of the changes you made.
1 parent 8c0d646 commit 93999c0

File tree

6 files changed

+175
-1
lines changed

6 files changed

+175
-1
lines changed

.changeset/sour-clocks-join.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@builder.io/react": patch
3+
"@builder.io/sdk-angular": patch
4+
"@builder.io/sdk-react-nextjs": patch
5+
"@builder.io/sdk-qwik": patch
6+
"@builder.io/sdk-react": patch
7+
"@builder.io/sdk-react-native": patch
8+
"@builder.io/sdk-solid": patch
9+
"@builder.io/sdk-svelte": patch
10+
"@builder.io/sdk-vue": patch
11+
---
12+
13+
Fix: centering items inside columns when columns has a fixed height

packages/react/src/blocks/Columns.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class ColumnsComponent extends React.Component<any> {
100100
className="builder-columns"
101101
css={{
102102
display: 'flex',
103+
height: '100%',
103104
...(this.props.stackColumnsAt !== 'never' && {
104105
[`@media (max-width: ${
105106
this.props.stackColumnsAt !== 'tablet'

packages/sdks-tests/src/e2e-tests/blocks.spec.ts

+34
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,40 @@ test.describe('Blocks', () => {
588588

589589
expect(textCenter).toBeCloseTo(columnCenter, 1);
590590
});
591+
592+
test('blocks are centered vertically when all blocks are individually centered and columns has a fixed height', async ({
593+
page,
594+
sdk,
595+
}) => {
596+
test.skip(checkIsRN(sdk));
597+
await page.goto('/columns-vertical-centering');
598+
599+
const columnsParent = page.locator(
600+
'xpath=//div[contains(@class, "builder-columns")]/ancestor::div[1]'
601+
);
602+
603+
const columnBox = await columnsParent.boundingBox();
604+
const textBoxes = await columnsParent.locator('.builder-text').all();
605+
606+
if (!columnBox || !textBoxes) {
607+
throw new Error('Could not get bounding boxes');
608+
}
609+
610+
const columnCenter = columnBox.y + columnBox.height / 2;
611+
612+
const textCenters = await Promise.all(
613+
textBoxes.map(async textBox => {
614+
const textBoxBox = await textBox.boundingBox();
615+
if (!textBoxBox) {
616+
throw new Error('Could not get bounding box');
617+
}
618+
return textBoxBox.y + textBoxBox.height / 2;
619+
})
620+
);
621+
622+
expect(textCenters[0]).toBeCloseTo(columnCenter, 1);
623+
expect(textCenters[1]).toBeCloseTo(columnCenter, 1);
624+
});
591625
});
592626

593627
test.describe('Embed', () => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
export const COLUMNS_VERTICAL_CENTERING = {
2+
ownerId: 'ad30f9a246614faaa6a03374f83554c9',
3+
lastUpdateBy: null,
4+
createdDate: 1742468200898,
5+
id: '34d8d0d89db2442cb3d0b739991fb67f',
6+
'@version': 4,
7+
name: 'columns-v-centering',
8+
modelId: '17c6065109ef4062ba083f5741f4ee6a',
9+
published: 'draft',
10+
meta: {
11+
kind: 'page',
12+
lastPreviewUrl:
13+
'http://localhost:5173/columns-v-centering?builder.space=ad30f9a246614faaa6a03374f83554c9&builder.user.permissions=read%2Ccreate%2Cpublish%2CeditCode%2CeditDesigns%2Cadmin%2CeditLayouts%2CeditLayers%2CeditContentPriority&builder.user.role.name=Admin&builder.user.role.id=admin&builder.cachebust=true&builder.preview=page&builder.noCache=true&builder.allowTextEdit=true&__builder_editing__=true&builder.overrides.page=34d8d0d89db2442cb3d0b739991fb67f&builder.overrides.34d8d0d89db2442cb3d0b739991fb67f=34d8d0d89db2442cb3d0b739991fb67f&builder.overrides.page:/columns-v-centering=34d8d0d89db2442cb3d0b739991fb67f&builder.options.locale=Default',
14+
hasLinks: false,
15+
},
16+
priority: -1015,
17+
query: [
18+
{
19+
'@type': '@builder.io/core:Query',
20+
property: 'urlPath',
21+
operator: 'is',
22+
value: '/columns-v-centering',
23+
},
24+
],
25+
data: {
26+
title: 'columns-v-centering',
27+
themeId: false,
28+
blocks: [
29+
{
30+
'@type': '@builder.io/sdk:Element',
31+
'@version': 2,
32+
id: 'builder-f1ae6670480d44bfa78a4a3f15ee584b',
33+
component: {
34+
name: 'Columns',
35+
options: {
36+
columns: [
37+
{
38+
blocks: [
39+
{
40+
'@type': '@builder.io/sdk:Element',
41+
'@version': 2,
42+
id: 'builder-5f09976df08d4a67b9780dcb38b9ba45',
43+
component: {
44+
name: 'Text',
45+
options: {
46+
text: 'text 1',
47+
},
48+
},
49+
responsiveStyles: {
50+
large: {
51+
display: 'flex',
52+
flexDirection: 'column',
53+
position: 'relative',
54+
flexShrink: '0',
55+
boxSizing: 'border-box',
56+
marginTop: 'auto',
57+
lineHeight: 'normal',
58+
height: 'auto',
59+
marginBottom: 'auto',
60+
},
61+
},
62+
},
63+
],
64+
},
65+
{
66+
blocks: [
67+
{
68+
'@type': '@builder.io/sdk:Element',
69+
'@version': 2,
70+
id: 'builder-f571ee77a16a45b08f59fdd36463ca5e',
71+
component: {
72+
name: 'Text',
73+
options: {
74+
text: 'text 2',
75+
},
76+
},
77+
responsiveStyles: {
78+
large: {
79+
display: 'flex',
80+
flexDirection: 'column',
81+
position: 'relative',
82+
flexShrink: '0',
83+
boxSizing: 'border-box',
84+
marginTop: 'auto',
85+
lineHeight: 'normal',
86+
height: 'auto',
87+
marginBottom: 'auto',
88+
},
89+
},
90+
},
91+
],
92+
},
93+
],
94+
space: 20,
95+
stackColumnsAt: 'tablet',
96+
reverseColumnsWhenStacked: false,
97+
},
98+
},
99+
responsiveStyles: {
100+
large: {
101+
display: 'flex',
102+
flexDirection: 'column',
103+
position: 'relative',
104+
flexShrink: '0',
105+
boxSizing: 'border-box',
106+
marginTop: '20px',
107+
height: '400px',
108+
},
109+
},
110+
},
111+
],
112+
},
113+
metrics: {
114+
clicks: 0,
115+
impressions: 0,
116+
},
117+
variations: {},
118+
lastUpdated: 1742468604796,
119+
testRatio: 1,
120+
createdBy: 'RuGeCLr9ryVt1xRazFYc72uWwIK2',
121+
lastUpdatedBy: 'RuGeCLr9ryVt1xRazFYc72uWwIK2',
122+
folders: [],
123+
};

packages/sdks-tests/src/specs/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ import { COLUMNS_VERTICAL_CENTER_FLEX } from './columns-vertical-center-flex.js'
8888
import { DYNAMIC_ELEMENT } from './dynamic-element.js';
8989
import { CUSTOM_CODE_DOM_UPDATE } from './custom-code-dom-update.js';
9090
import { NEW_BLOCK_ADD } from './new-block-add.js';
91-
9291
import { DYNAMIC_BUTTON } from './dynamic-button.js';
92+
import { COLUMNS_VERTICAL_CENTERING } from './columns-vertical-centering.js';
9393
import { SECTION_CHILDREN } from './section-children.js';
94+
9495
function isBrowser(): boolean {
9596
return typeof window !== 'undefined' && typeof document !== 'undefined';
9697
}
@@ -284,6 +285,7 @@ export const PAGES: Record<string, Page> = {
284285
'/custom-code-dom-update': { content: CUSTOM_CODE_DOM_UPDATE },
285286
'/new-block-add': { content: NEW_BLOCK_ADD },
286287
'/dynamic-button': { content: DYNAMIC_BUTTON },
288+
'/columns-vertical-centering': { content: COLUMNS_VERTICAL_CENTERING },
287289
'/section-children': { content: SECTION_CHILDREN },
288290
} as const;
289291

packages/sdks/src/blocks/columns/columns.lite.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ export default function Columns(props: ColumnProps) {
223223
css={{
224224
display: 'flex',
225225
lineHeight: 'normal',
226+
height: '100%',
226227
}}
227228
style={state.columnsCssVars()}
228229
{...useTarget({

0 commit comments

Comments
 (0)