Skip to content

[Fix]: #1626 Width Column Layout #1675

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 14, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const ColWrapper = styled(Col)<{
$minWidth?: string,
$matchColumnsHeight: boolean,
}>`
min-width: ${(props) => props.$minWidth || 'auto'};
> div {
height: ${(props) => props.$matchColumnsHeight ? `calc(100% - ${props.$style?.padding || 0} - ${props.$style?.padding || 0})` : 'auto'};
border-radius: ${(props) => props.$style?.radius};
Expand Down Expand Up @@ -122,6 +123,53 @@ const ColumnContainer = (props: ColumnContainerProps) => {
);
};

// Function to apply min-widths to grid template columns
const applyMinWidthsToGridColumns = (columnsDef: string, minWidths: (string | null)[] = []) => {
// Handle empty case
if (!columnsDef?.trim()) return '';

// Handle repeat() functions with special parsing
if (columnsDef.includes('repeat(')) {
// For complex repeat patterns, we should return as-is to avoid breaking the layout
// A more complex parser would be needed to fully support repeat with minmax
return columnsDef;
}

const columns = columnsDef.trim().split(/\s+/);

const newColumns = columns.map((col, index) => {
const minWidth = minWidths[index];

// Skip if no minWidth provided for this column
if (!minWidth) {
return col;
}

// Keywords that should never be wrapped in minmax()
const keywords = ['auto', 'min-content', 'max-content', 'fit-content', 'subgrid'];
if (keywords.some(keyword => col === keyword)) {
return col;
}

// Functions that should never be wrapped in minmax()
if (col.includes('(') && col.includes(')')) {
// Already includes a function like calc(), minmax(), etc.
return col;
}

// Determine if column is flexible and can be wrapped with minmax
// - fr units (e.g., "1fr", "2.5fr")
// - percentage values (e.g., "50%")
// - length values (px, em, rem, etc.)
const isFlexible = /fr$/.test(col) ||
/%$/.test(col) ||
/^\d+(\.\d+)?(px|em|rem|vh|vw|vmin|vmax|cm|mm|in|pt|pc)$/.test(col);

return isFlexible ? `minmax(${minWidth}, ${col})` : col;
});

return newColumns.join(' ');
};

const ColumnLayout = (props: ColumnLayoutProps) => {
let {
Expand All @@ -138,6 +186,12 @@ const ColumnLayout = (props: ColumnLayoutProps) => {
mainScrollbar
} = props;

// Extract minWidths from columns
const minWidths = columns.map(column => column.minWidth || null);

// Apply min-widths to grid template columns
const gridTemplateColumns = applyMinWidthsToGridColumns(templateColumns, minWidths);

return (
<BackgroundColorContext.Provider value={props.style.background}>
<DisabledContext.Provider value={props.disabled}>
Expand All @@ -146,7 +200,7 @@ const ColumnLayout = (props: ColumnLayoutProps) => {
<ContainWrapper $style={{
...props.style,
display: "grid",
gridTemplateColumns: templateColumns,
gridTemplateColumns: gridTemplateColumns,
columnGap,
gridTemplateRows: templateRows,
rowGap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const ColWrapper = styled(Col)<{
flex-basis: ${(props) =>
props.$rowBreak
? `calc(100% / var(--columns))` // Force exact column distribution
: `clamp(${props.$minWidth}, 100% / var(--columns), 100%)`}; // MinWidth respected
: `clamp(${props.$minWidth || "0px"}, calc(100% / var(--columns)), 100%)`}; // MinWidth respected

min-width: ${(props) => props.$minWidth}; // Ensure minWidth is respected
max-width: 100%; // Prevent more columns than allowed
Expand Down Expand Up @@ -237,7 +237,8 @@ const ResponsiveLayout = (props: ResponsiveLayoutProps) => {
if (!containers[id]) return null;
const containerProps = containers[id].children;

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

return (
<ColWrapper
Expand All @@ -247,7 +248,7 @@ const ResponsiveLayout = (props: ResponsiveLayoutProps) => {
sm={rowBreak ? 24 / numberOfColumns : undefined}
xs={rowBreak ? 24 / numberOfColumns : undefined}
$style={props.columnStyle}
$minWidth={`${calculatedWidth}px`}
$minWidth={columnMinWidth}
$matchColumnsHeight={matchColumnsHeight}
$rowBreak={rowBreak}
>
Expand Down
Loading