Repository navigation
Grid: Add option to stretch columns with auto-fit for better layout flexibility #79356
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
tellthemachines
merged 4 commits into
WordPress:trunk
from
shrivastavanolo:add/auto-fit-option-for-grid-layout
Jun 25, 2026
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
6ec99bf
Grid: Add option to stretch columns with auto-fit for better layout f…
shrivastavanolo e2ec38b
Merge branch 'trunk' into add/auto-fit-option-for-grid-layout
shrivastavanolo b81a2d7
Grid: Fix autoFit viewport override support and explicit boolean storage
shrivastavanolo c9f4f15
chore: add backport changelog for wordpress-develop PR
shrivastavanolo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import { | |
| Flex, | ||
| FlexItem, | ||
| RangeControl, | ||
| ToggleControl, | ||
| __experimentalNumberControl as NumberControl, | ||
| __experimentalToggleGroupControl as ToggleGroupControl, | ||
| __experimentalToggleGroupControlOption as ToggleGroupControlOption, | ||
|
|
@@ -81,6 +82,9 @@ export default { | |
| const showMinWidthControl = | ||
| ! layout?.isManualPlacement || | ||
| window.__experimentalEnableGridInteractivity; | ||
| // Auto-fit/auto-fill only applies when grid items are placed | ||
| // automatically, so the control is irrelevant in manual placement mode. | ||
| const showFillControl = ! layout?.isManualPlacement; | ||
| const defaultColumnCount = layout.isManualPlacement ? 3 : undefined; | ||
| const hasLayoutValue = ( key, defaultValue ) => | ||
| ( layout?.[ key ] ?? defaultValue ) !== | ||
|
|
@@ -92,6 +96,7 @@ export default { | |
| hasLayoutValue( 'rowCount' ); | ||
| const hasMinimumColumnWidthValue = () => | ||
| hasLayoutValue( 'minimumColumnWidth' ); | ||
| const hasFillValue = () => hasLayoutValue( 'autoFit', false ); | ||
| const resetGridType = () => | ||
| onChange( | ||
| cleanEmptyObject( { | ||
|
|
@@ -116,6 +121,13 @@ export default { | |
| minimumColumnWidth: resetLayout?.minimumColumnWidth, | ||
| } ) | ||
| ); | ||
| const resetFill = () => | ||
| onChange( | ||
| cleanEmptyObject( { | ||
| ...layout, | ||
| autoFit: resetLayout?.autoFit, | ||
| } ) | ||
| ); | ||
|
|
||
| return ( | ||
| <> | ||
|
|
@@ -162,6 +174,19 @@ export default { | |
| /> | ||
| </ToolsPanelItem> | ||
| ) } | ||
| { showFillControl && ( | ||
| <ToolsPanelItem | ||
| label={ __( 'Fill available space' ) } | ||
| hasValue={ hasFillValue } | ||
| onDeselect={ resetFill } | ||
| panelId={ clientId } | ||
| > | ||
| <GridLayoutFillControl | ||
| layout={ layout } | ||
| onChange={ onChange } | ||
| /> | ||
| </ToolsPanelItem> | ||
| ) } | ||
| </> | ||
| ); | ||
| }, | ||
|
|
@@ -188,8 +213,13 @@ export default { | |
| minimumColumnWidth = null, | ||
| columnCount = null, | ||
| rowCount = null, | ||
| autoFit = false, | ||
| } = effectiveLayout; | ||
|
|
||
| // When enabled, columns stretch to fill the available space using | ||
| // `auto-fit`; otherwise empty tracks are preserved with `auto-fill`. | ||
| const autoPlacement = autoFit ? 'auto-fit' : 'auto-fill'; | ||
|
|
||
| // Check that the grid layout attributes are of the correct type, so that we don't accidentally | ||
| // write code that stores a string attribute instead of a number. | ||
| if ( process.env.NODE_ENV === 'development' ) { | ||
|
|
@@ -205,6 +235,9 @@ export default { | |
| if ( rowCount && typeof rowCount !== 'number' ) { | ||
| throw new Error( 'rowCount must be a number' ); | ||
| } | ||
| if ( autoFit && typeof autoFit !== 'boolean' ) { | ||
| throw new Error( 'autoFit must be a boolean' ); | ||
| } | ||
| } | ||
|
|
||
| // Use the global blockGap value as fallback when available. | ||
|
|
@@ -256,15 +289,15 @@ export default { | |
| columnCount - 1 | ||
| }) ) / ${ columnCount })`; | ||
| rules.push( | ||
| `grid-template-columns: repeat(auto-fill, minmax(${ maxValue }, 1fr))` | ||
| `grid-template-columns: repeat(${ autoPlacement }, minmax(${ maxValue }, 1fr))` | ||
| ); | ||
| } else if ( shouldOutputGridColumns && columnCount ) { | ||
| rules.push( | ||
| `grid-template-columns: repeat(${ columnCount }, minmax(0, 1fr))` | ||
| ); | ||
| } else if ( shouldOutputGridColumns ) { | ||
| rules.push( | ||
| `grid-template-columns: repeat(auto-fill, minmax(min(${ | ||
| `grid-template-columns: repeat(${ autoPlacement }, minmax(min(${ | ||
| minimumColumnWidth || '12rem' | ||
| }, 100%), 1fr))` | ||
| ); | ||
|
|
@@ -488,6 +521,28 @@ function GridLayoutColumnsAndRowsControl( { | |
| ); | ||
| } | ||
|
|
||
| // Enables stretching grid columns to fill the available space (auto-fit) | ||
| // instead of leaving empty tracks at the end of a row (auto-fill). | ||
| function GridLayoutFillControl( { layout, onChange } ) { | ||
| const { autoFit = false } = layout; | ||
|
|
||
| return ( | ||
| <ToggleControl | ||
| label={ __( 'Fill available space' ) } | ||
| help={ __( | ||
| 'Stretch columns to fill the available space, instead of leaving gaps when there are too few items to fill a row.' | ||
| ) } | ||
| checked={ autoFit } | ||
| onChange={ ( value ) => | ||
| onChange( { | ||
| ...layout, | ||
| autoFit: value || undefined, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might need to make sure that autoFit can explicitly be set to false, in case the default value is true and false is set as a viewport override (because we'll need a rule to be output in that case). |
||
| } ) | ||
| } | ||
| /> | ||
| ); | ||
| } | ||
|
|
||
| // Enables switching between grid types | ||
| function GridLayoutTypeControl( { layout, onChange } ) { | ||
| const { columnCount, rowCount, minimumColumnWidth, isManualPlacement } = | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should link to this PR, not the issue.