Skip to content

Commit 71fa1f2

Browse files
Merge pull request #1675 from iamfaran/fix/1626-column-layout
[Fix]: #1626 Width Column Layout
2 parents 520bfca + 9eb9341 commit 71fa1f2

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

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

+55-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ const ColWrapper = styled(Col)<{
7272
$minWidth?: string,
7373
$matchColumnsHeight: boolean,
7474
}>`
75+
min-width: ${(props) => props.$minWidth || 'auto'};
7576
> div {
7677
height: ${(props) => props.$matchColumnsHeight ? `calc(100% - ${props.$style?.padding || 0} - ${props.$style?.padding || 0})` : 'auto'};
7778
border-radius: ${(props) => props.$style?.radius};
@@ -122,6 +123,53 @@ const ColumnContainer = (props: ColumnContainerProps) => {
122123
);
123124
};
124125

126+
// Function to apply min-widths to grid template columns
127+
const applyMinWidthsToGridColumns = (columnsDef: string, minWidths: (string | null)[] = []) => {
128+
// Handle empty case
129+
if (!columnsDef?.trim()) return '';
130+
131+
// Handle repeat() functions with special parsing
132+
if (columnsDef.includes('repeat(')) {
133+
// For complex repeat patterns, we should return as-is to avoid breaking the layout
134+
// A more complex parser would be needed to fully support repeat with minmax
135+
return columnsDef;
136+
}
137+
138+
const columns = columnsDef.trim().split(/\s+/);
139+
140+
const newColumns = columns.map((col, index) => {
141+
const minWidth = minWidths[index];
142+
143+
// Skip if no minWidth provided for this column
144+
if (!minWidth) {
145+
return col;
146+
}
147+
148+
// Keywords that should never be wrapped in minmax()
149+
const keywords = ['auto', 'min-content', 'max-content', 'fit-content', 'subgrid'];
150+
if (keywords.some(keyword => col === keyword)) {
151+
return col;
152+
}
153+
154+
// Functions that should never be wrapped in minmax()
155+
if (col.includes('(') && col.includes(')')) {
156+
// Already includes a function like calc(), minmax(), etc.
157+
return col;
158+
}
159+
160+
// Determine if column is flexible and can be wrapped with minmax
161+
// - fr units (e.g., "1fr", "2.5fr")
162+
// - percentage values (e.g., "50%")
163+
// - length values (px, em, rem, etc.)
164+
const isFlexible = /fr$/.test(col) ||
165+
/%$/.test(col) ||
166+
/^\d+(\.\d+)?(px|em|rem|vh|vw|vmin|vmax|cm|mm|in|pt|pc)$/.test(col);
167+
168+
return isFlexible ? `minmax(${minWidth}, ${col})` : col;
169+
});
170+
171+
return newColumns.join(' ');
172+
};
125173

126174
const ColumnLayout = (props: ColumnLayoutProps) => {
127175
let {
@@ -138,6 +186,12 @@ const ColumnLayout = (props: ColumnLayoutProps) => {
138186
mainScrollbar
139187
} = props;
140188

189+
// Extract minWidths from columns
190+
const minWidths = columns.map(column => column.minWidth || null);
191+
192+
// Apply min-widths to grid template columns
193+
const gridTemplateColumns = applyMinWidthsToGridColumns(templateColumns, minWidths);
194+
141195
return (
142196
<BackgroundColorContext.Provider value={props.style.background}>
143197
<DisabledContext.Provider value={props.disabled}>
@@ -146,7 +200,7 @@ const ColumnLayout = (props: ColumnLayoutProps) => {
146200
<ContainWrapper $style={{
147201
...props.style,
148202
display: "grid",
149-
gridTemplateColumns: templateColumns,
203+
gridTemplateColumns: gridTemplateColumns,
150204
columnGap,
151205
gridTemplateRows: templateRows,
152206
rowGap,

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const ColWrapper = styled(Col)<{
8787
flex-basis: ${(props) =>
8888
props.$rowBreak
8989
? `calc(100% / var(--columns))` // Force exact column distribution
90-
: `clamp(${props.$minWidth}, 100% / var(--columns), 100%)`}; // MinWidth respected
90+
: `clamp(${props.$minWidth || "0px"}, calc(100% / var(--columns)), 100%)`}; // MinWidth respected
9191
9292
min-width: ${(props) => props.$minWidth}; // Ensure minWidth is respected
9393
max-width: 100%; // Prevent more columns than allowed
@@ -237,7 +237,8 @@ const ResponsiveLayout = (props: ResponsiveLayoutProps) => {
237237
if (!containers[id]) return null;
238238
const containerProps = containers[id].children;
239239

240-
const calculatedWidth = 100 / numberOfColumns;
240+
// Use the actual minWidth from column configuration instead of calculated width
241+
const columnMinWidth = column.minWidth || `${100 / numberOfColumns}px`;
241242

242243
return (
243244
<ColWrapper
@@ -247,7 +248,7 @@ const ResponsiveLayout = (props: ResponsiveLayoutProps) => {
247248
sm={rowBreak ? 24 / numberOfColumns : undefined}
248249
xs={rowBreak ? 24 / numberOfColumns : undefined}
249250
$style={props.columnStyle}
250-
$minWidth={`${calculatedWidth}px`}
251+
$minWidth={columnMinWidth}
251252
$matchColumnsHeight={matchColumnsHeight}
252253
$rowBreak={rowBreak}
253254
>

0 commit comments

Comments
 (0)