Skip to content

Commit a362635

Browse files
fix responsiveLayout issues
1 parent f4f6941 commit a362635

File tree

1 file changed

+78
-65
lines changed

1 file changed

+78
-65
lines changed

client/packages/lowcoder/src/comps/comps/responsiveLayout/responsiveLayout.tsx

Lines changed: 78 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ const RowWrapper = styled(Row)<{
5151
$style: ResponsiveLayoutRowStyleType;
5252
$animationStyle: AnimationStyleType;
5353
$showScrollbar: boolean;
54-
$columnCount: number;
5554
}>`
5655
${(props) => props.$animationStyle}
5756
height: 100%;
@@ -67,8 +66,6 @@ const RowWrapper = styled(Row)<{
6766
display: ${(props) => (props.$showScrollbar ? 'block' : 'none')};
6867
}
6968
${props => getBackgroundStyle(props.$style)}
70-
71-
--columns: ${(props) => props.$columnCount || 3};
7269
`;
7370

7471
const ColWrapper = styled(Col)<{
@@ -79,17 +76,31 @@ const ColWrapper = styled(Col)<{
7976
}>`
8077
display: flex;
8178
flex-direction: column;
82-
flex-grow: 1;
83-
84-
// When rowBreak is true, columns are stretched evenly based on configured number
85-
// When rowBreak is false, they stay at minWidth but break only if necessary
86-
flex-basis: ${(props) =>
87-
props.$rowBreak
88-
? `calc(100% / var(--columns))` // Force exact column distribution
89-
: `clamp(${props.$minWidth || "0px"}, calc(100% / var(--columns)), 100%)`}; // MinWidth respected
79+
80+
/* When rowBreak is true: columns stretch evenly to fill available space */
81+
/* When rowBreak is false: columns take available space but respect minWidth */
82+
flex-grow: ${(props) => props.$rowBreak ? '1' : '1'};
83+
flex-shrink: ${(props) => {
84+
if (props.$rowBreak) {
85+
return '1'; // Can shrink when rowBreak is true
86+
} else {
87+
// When rowBreak is false, only allow shrinking if no minWidth is set
88+
return props.$minWidth ? '0' : '1';
89+
}
90+
}};
91+
flex-basis: ${(props) => {
92+
if (props.$rowBreak) {
93+
// When rowBreak is true, distribute columns evenly
94+
return '0%';
95+
} else {
96+
// When rowBreak is false, use minWidth if specified, otherwise auto
97+
return props.$minWidth || 'auto';
98+
}
99+
}};
90100
91-
min-width: ${(props) => props.$minWidth}; // Ensure minWidth is respected
92-
max-width: 100%; // Prevent more columns than allowed
101+
/* Ensure minWidth is respected */
102+
min-width: ${(props) => props.$minWidth || 'auto'};
103+
max-width: 100%;
93104
94105
> div {
95106
height: ${(props) => (props.$matchColumnsHeight ? "100%" : "auto")};
@@ -203,68 +214,70 @@ const ResponsiveLayout = (props: ResponsiveLayoutProps) => {
203214
const effectiveWidth = useComponentWidth ? componentWidth ?? safeScreenInfo.width : safeScreenInfo.width;
204215
const effectiveDeviceType = useComponentWidth ? getDeviceType(effectiveWidth || 1000) : safeScreenInfo.deviceType;
205216

206-
// Get columns per row based on device type
207-
let configuredColumnsPerRow = effectiveDeviceType === "mobile"
217+
// Get current columns per row based on device type
218+
const currentColumnsPerRow = effectiveDeviceType === "mobile"
208219
? columnPerRowSM
209220
: effectiveDeviceType === "tablet"
210221
? columnPerRowMD
211222
: columnPerRowLG;
212223

213-
// Calculate max columns that fit based on minWidth
214-
let maxColumnsThatFit = componentWidth
215-
? Math.floor(componentWidth / Math.max(...columns.map((col) => parseFloat(col.minWidth || "0"))))
216-
: configuredColumnsPerRow;
217-
218-
// Determine actual number of columns
219-
let numberOfColumns = rowBreak ? configuredColumnsPerRow : Math.min(maxColumnsThatFit, totalColumns);
224+
// Group columns into rows based on currentColumnsPerRow only when rowBreak is true
225+
const columnRows = rowBreak ? (() => {
226+
const rows = [];
227+
for (let i = 0; i < columns.length; i += currentColumnsPerRow) {
228+
rows.push(columns.slice(i, i + currentColumnsPerRow));
229+
}
230+
return rows;
231+
})() : [columns]; // When rowBreak is false, put all columns in a single row
220232

221233
return (
222234
<BackgroundColorContext.Provider value={props.style.background}>
223235
<DisabledContext.Provider value={props.disabled}>
224236
<div ref={containerRef} style={{ padding: style.margin, height: "100%" }}>
225-
<RowWrapper
226-
$style={{ ...style }}
227-
$animationStyle={animationStyle}
228-
$showScrollbar={mainScrollbar}
229-
$columnCount={numberOfColumns}
230-
wrap={rowBreak}
231-
gutter={[horizontalSpacing, verticalSpacing]}
232-
>
233-
{columns.map((column) => {
234-
const id = String(column.id);
235-
const childDispatch = wrapDispatch(wrapDispatch(dispatch, "containers"), id);
236-
if (!containers[id] || column.hidden) return null;
237-
const containerProps = containers[id].children;
238-
239-
// Use the actual minWidth from column configuration instead of calculated width
240-
const columnMinWidth = column.minWidth || `${100 / numberOfColumns}px`;
241-
242-
return (
243-
<ColWrapper
244-
key={id}
245-
lg={rowBreak ? 24 / numberOfColumns : undefined}
246-
md={rowBreak ? 24 / numberOfColumns : undefined}
247-
sm={rowBreak ? 24 / numberOfColumns : undefined}
248-
xs={rowBreak ? 24 / numberOfColumns : undefined}
249-
$style={props.columnStyle}
250-
$minWidth={columnMinWidth}
251-
$matchColumnsHeight={matchColumnsHeight}
252-
$rowBreak={rowBreak}
253-
>
254-
<ColumnContainer
255-
layout={containerProps.layout.getView()}
256-
items={gridItemCompToGridItems(containerProps.items.getView())}
257-
positionParams={containerProps.positionParams.getView()}
258-
dispatch={childDispatch}
259-
autoHeight={props.autoHeight}
260-
horizontalGridCells={horizontalGridCells}
261-
style={columnStyle}
262-
emptyRows={props.verticalGridCells}
263-
/>
264-
</ColWrapper>
265-
);
266-
})}
267-
</RowWrapper>
237+
{columnRows.map((row, rowIndex) => (
238+
<RowWrapper
239+
key={rowIndex}
240+
$style={{ ...style }}
241+
$animationStyle={animationStyle}
242+
$showScrollbar={mainScrollbar}
243+
wrap={rowBreak}
244+
gutter={[horizontalSpacing, verticalSpacing]}
245+
>
246+
{row.map((column) => {
247+
const id = String(column.id);
248+
const childDispatch = wrapDispatch(wrapDispatch(dispatch, "containers"), id);
249+
if (!containers[id] || column.hidden) return null;
250+
const containerProps = containers[id].children;
251+
252+
const columnMinWidth = column.minWidth;
253+
254+
return (
255+
<ColWrapper
256+
key={id}
257+
lg={rowBreak ? 24 / columnPerRowLG : undefined}
258+
md={rowBreak ? 24 / columnPerRowMD : undefined}
259+
sm={rowBreak ? 24 / columnPerRowSM : undefined}
260+
xs={rowBreak ? 24 / columnPerRowSM : undefined}
261+
$style={props.columnStyle}
262+
$minWidth={columnMinWidth}
263+
$matchColumnsHeight={matchColumnsHeight}
264+
$rowBreak={rowBreak}
265+
>
266+
<ColumnContainer
267+
layout={containerProps.layout.getView()}
268+
items={gridItemCompToGridItems(containerProps.items.getView())}
269+
positionParams={containerProps.positionParams.getView()}
270+
dispatch={childDispatch}
271+
autoHeight={props.autoHeight}
272+
horizontalGridCells={horizontalGridCells}
273+
style={columnStyle}
274+
emptyRows={props.verticalGridCells}
275+
/>
276+
</ColWrapper>
277+
);
278+
})}
279+
</RowWrapper>
280+
))}
268281
</div>
269282
</DisabledContext.Provider>
270283
</BackgroundColorContext.Provider>

0 commit comments

Comments
 (0)