Skip to content
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

Try adding a grid layout type #49018

Merged
merged 11 commits into from
Mar 24, 2023
Merged

Try adding a grid layout type #49018

merged 11 commits into from
Mar 24, 2023

Conversation

tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Mar 13, 2023

What?

Fixes #47809.

Adds a new "grid" layout type, and adds it as a variation to the Group block to enable testing.

Currently the only allowed grid template is a repeating auto-fill, with a single control to set the minimum column width.

We could potentially add a variant with a fixed number of columns to create the second layout type @SaxonF shows in his demo.

~~Update: I just introduced a "responsive" toggle which, when on, shows the column width control and outputs an "auto-fill" template, and when off provides a column number range and outputs a static number of responsive columns. ~~

The controls are very much for testing purposes, we'll probably want to refine this UI a bit 😅

Another thing that might be useful is adding controls to grid children to allow them to span more than one column.

Testing Instructions

  1. Add a Grid block to a post or template.
  2. Add some blocks inside the Grid.
  3. In the sidebar, in the "Layout" panel, change the column width values with the "Minimum column width" control.

Testing Instructions for Keyboard

Instructions above should work for keyboard. The block sidebar can be accessed from the block by pressing Tab twice, then tabbing through the sections until "Layout" is reached.

Screenshots or screencast

@github-actions
Copy link

github-actions bot commented Mar 13, 2023

Size Change: +1.72 kB (0%)

Total Size: 1.34 MB

Filename Size Change
build/block-editor/index.min.js 198 kB +884 B (0%)
build/block-editor/style-rtl.css 14.5 kB +40 B (0%)
build/block-editor/style.css 14.5 kB +41 B (0%)
build/block-library/blocks/search/style-rtl.css 408 B -1 B (0%)
build/block-library/index.min.js 202 kB +517 B (0%)
build/block-library/style.css 12.7 kB -2 B (0%)
build/blocks/index.min.js 51.1 kB +44 B (0%)
build/components/index.min.js 208 kB +129 B (0%)
build/components/style-rtl.css 11.7 kB +16 B (0%)
build/components/style.css 11.7 kB +17 B (0%)
build/edit-site/index.min.js 65.2 kB +11 B (0%)
build/style-engine/index.min.js 1.55 kB +20 B (+1%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 483 B
build/block-directory/index.min.js 7.2 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/content-rtl.css 4.11 kB
build/block-editor/content.css 4.1 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 91 B
build/block-library/blocks/avatar/style.css 91 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 587 B
build/block-library/blocks/button/editor.css 587 B
build/block-library/blocks/button/style-rtl.css 628 B
build/block-library/blocks/button/style.css 627 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/cover/style-rtl.css 1.6 kB
build/block-library/blocks/cover/style.css 1.59 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 265 B
build/block-library/blocks/file/style.css 265 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 984 B
build/block-library/blocks/gallery/editor.css 988 B
build/block-library/blocks/gallery/style-rtl.css 1.55 kB
build/block-library/blocks/gallery/style.css 1.55 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 830 B
build/block-library/blocks/image/editor.css 829 B
build/block-library/blocks/image/style-rtl.css 652 B
build/block-library/blocks/image/style.css 652 B
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 716 B
build/block-library/blocks/navigation-link/editor.css 715 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/editor-rtl.css 2.13 kB
build/block-library/blocks/navigation/editor.css 2.14 kB
build/block-library/blocks/navigation/style-rtl.css 2.22 kB
build/block-library/blocks/navigation/style.css 2.2 kB
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB
build/block-library/blocks/navigation/view.min.js 447 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 401 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 501 B
build/block-library/blocks/post-comments-form/style.css 501 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 134 B
build/block-library/blocks/post-excerpt/style.css 134 B
build/block-library/blocks/post-featured-image/editor-rtl.css 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-featured-image/style-rtl.css 322 B
build/block-library/blocks/post-featured-image/style.css 322 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 463 B
build/block-library/blocks/query/editor.css 463 B
build/block-library/blocks/quote/style-rtl.css 222 B
build/block-library/blocks/quote/style.css 222 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style.css 406 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 489 B
build/block-library/blocks/site-logo/editor.css 489 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 433 B
build/block-library/blocks/table/editor.css 433 B
build/block-library/blocks/table/style-rtl.css 651 B
build/block-library/blocks/table/style.css 650 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 404 B
build/block-library/blocks/template-part/editor.css 404 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 179 B
build/block-library/blocks/video/style.css 179 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.6 kB
build/block-library/editor.css 11.6 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 12.7 kB
build/block-library/theme-rtl.css 698 B
build/block-library/theme.css 703 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/compose/index.min.js 12.4 kB
build/core-data/index.min.js 16.3 kB
build/customize-widgets/index.min.js 12.2 kB
build/customize-widgets/style-rtl.css 1.41 kB
build/customize-widgets/style.css 1.41 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.62 kB
build/date/index.min.js 40.4 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.72 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/index.min.js 34.8 kB
build/edit-post/style-rtl.css 7.59 kB
build/edit-post/style.css 7.58 kB
build/edit-site/style-rtl.css 10.2 kB
build/edit-site/style.css 10.2 kB
build/edit-widgets/index.min.js 17.3 kB
build/edit-widgets/style-rtl.css 4.56 kB
build/edit-widgets/style.css 4.56 kB
build/editor/index.min.js 45.8 kB
build/editor/style-rtl.css 3.54 kB
build/editor/style.css 3.53 kB
build/element/index.min.js 4.95 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 7.26 kB
build/format-library/style-rtl.css 557 B
build/format-library/style.css 556 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/keycodes/index.min.js 1.94 kB
build/list-reusable-blocks/index.min.js 2.14 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.99 kB
build/notices/index.min.js 977 B
build/plugins/index.min.js 1.95 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.35 kB
build/primitives/index.min.js 960 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 937 B
build/react-i18n/index.min.js 702 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.75 kB
build/reusable-blocks/index.min.js 2.26 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 2.09 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 650 B
build/url/index.min.js 3.74 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 1.09 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.3 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a great feature to begin with @tellthemachines! Love the idea of using minimum column width with a max of 1fr, the auto-fill behaviour tests very nicely for me across a range of viewport sizes.

Also, by conditionally outputting grid-template-columns only if minimumColumnWidth is set, it means that we're not boxing ourselves in for future rules that might require a different value for grid-template-columns 👍

Just left a comment about the base styling rules, but this is looking really promising to me as a useful MVP. It's also really nice seeing the Grid option in the variations list, it's going to be a fun tool for folks to play with 😀

image

lib/theme.json Outdated
"slug": "grid",
"className": "is-layout-grid",
"displayMode": "grid",
"baseStyles": [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we might need to include the margin: 0 rule from baseStyles used by the flex layout, too. Otherwise the user agent stylesheet margin rules for e.g. p tags apply, affecting the gap:

image

@@ -1341,8 +1341,7 @@ protected function get_layout_styles( $block_metadata ) {
$base_style_rules = _wp_array_get( $layout_definition, array( 'baseStyles' ), array() );

if (
! empty( $class_name ) &&
! empty( $base_style_rules )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this change is to allow the block of code to be reachable if $base_style_rules is empty? Tiny nit: would it be worth retaining a check, but instead have it check is_array( $base_style_rules ) since the code below will attempt to iterate over $base_style_rules? (This is just to make sure that anything setting null or false won't throw an error)


return (
<UnitControl
size={ '__unstable-large' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a label to this component? E.g. label={ __( 'Minimum column width ' ) }?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a great idea!

@tellthemachines
Copy link
Contributor Author

Thanks for the feedback @andrewserong !

just pushed an update with an alternative, static column number style. It behaves exactly like Saxon's demo in that the columns just squish on smaller viewports, with no reduction in column number. This is probably something we'll want to iterate on 😅 and it might be nice to give container queries a try in this context. My main question is would it be best to provide responsive behaviour via queries behind the scenes or configurable via UI?

cc @SaxonF @WordPress/gutenberg-design

@github-actions
Copy link

github-actions bot commented Mar 14, 2023

Flaky tests detected in 099db1e.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4497336703
📝 Reported issues:

>
<Path d="m20.30137,-0.00025l-18.9728,0c-0.86524,0.07234 -1.41711,0.79149 -1.41711,1.89149l0,12.64468c0,0.6 0.73401,0.96383 1.0304,0.96383l19.67469,0.03617c0.29639,0 1.0304,-0.4 1.0304,-1l-0.03576,-12.7532c0,-1.1 -0.76644,-1.78297 -1.30983,-1.78297zm0.52975,16.60851l-19.99654,-0.03617c-0.29639,0 -0.92312,0.36383 -0.92312,0.96383l-0.03576,12.68085c0,1.1 0.8022,1.81915 1.34559,1.81915l19.00857,0c0.54339,0 1.45287,-0.71915 1.45287,-1.81915l0,-12.53617c0,-0.6 -0.5552,-1.07234 -0.8516,-1.07234z" />
<Path d="m42.73056,-0.03617l-18.59217,0c-0.84788,0.07234 -1.38868,0.79149 -1.38868,1.89149l0,12.64468c0,0.6 0.71928,0.96383 1.00973,0.96383l19.27997,0.03617c0.29045,0 1.00973,-0.4 1.00973,-1l-0.03504,-12.7532c0,-1.1 -0.75106,-1.78297 -1.28355,-1.78297zm0.51912,16.60851l-19.59537,-0.03617c-0.29045,0 -0.9046,0.36383 -0.9046,0.96383l-0.03504,12.68085c0,1.1 0.78611,1.81915 1.31859,1.81915l18.62721,0c0.53249,0 1.42372,-0.71915 1.42372,-1.81915l0,-12.53617c0,-0.6 -0.54407,-1.07234 -0.83451,-1.07234z" />
</SVG>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improvised a grid icon here but we'll probably want a proper one at some point 😄

@tellthemachines
Copy link
Contributor Author

I put up a draft that applies the static grid layout to Post Template in #49050. I think that highlights the potential problems of having a purely static column number; it definitely feels like there should be some responsive behaviour in place.

@SaxonF
Copy link
Contributor

SaxonF commented Mar 14, 2023

Exciting stuff @tellthemachines ! This looks like it could be a really great starting point for grid and lead into on canvas editing. I kind of see this new layout type as a "snap to grid" option that replaces the need for the old columns block.

+1 to gap/block spacing driven by spacing scales.

Another thing that might be useful is adding controls to grid children to allow them to span more than one column.

+1 thinking we add columns range to dimensions panel, either replacing width or in addition to.

image

My main question is would it be best to provide responsive behaviour via queries behind the scenes or configurable via UI?

This is tricky as we want to lean into intrinsic layouts where possible. If we wanted to adopt similarish behaviour to the columns block we could either:

  • reduce number of columns when scaling viewport (like this)
  • or just reduce to single column (replicate stack on mobile setting)

@andrewserong
Copy link
Contributor

I think that highlights the potential problems of having a purely static column number; it definitely feels like there should be some responsive behaviour in place.

Agreed. One of the things I really like about the auto-fill behaviour of the minimumColumnWidth option is that it just scales so beautifully across viewports without any media queries. It feels like it could be a good default option for the Post Template block, where a user might then see the effective number of columns as they interact with the minimum width control?

Or another (potentially improbable) idea 😅, what if the column number could be treated as "fuzzy" or "explicit" (or something like that), and if it's fuzzy, then it's actually just setting a minimumColumnWidth behind the scenes, rather than an explicit column number — but to the user it would appear as if they're adjusting the number of columns. Might be tricky to pull off, though, as it'd probably involve the UI observing how much space is currently available when the user adjusts the value 🤔

@jasmussen
Copy link
Contributor

Exciting stuff! A quick GIF showing the inspector controls toggling responsive on/off, and tinkering with the min-width control for child blocks:

grid block

Already starting to look like a better alternative to the Columns block. Small detail, I couldn't click/drag inside the input slider to increment/decrement. We might also want a input+slider combo for this. Also, thanks for using the 40px controls from the start 👌

The term "Minimum width" is good. To Saxon's point, it leans into the intrinsic responsiveness stuff, and it allows the block to do its magic and stay responsive. There's a visualization challenge to think about in the future, which is shared with the Row block's width controls: a min. width doesn't have a discernible effect in the canvas until the value exceeds a threshold of needing to wrap. It's visible in the GIF: I change the numbers but there's no visible effect, for a while, in the canvas. This is also a challenge if we ever want to add resize handles in the canvas — not sure we want that — but something to think about. A solution might be a visualizer, similar to the margin visualizers we have: a blue overlay shown while interacting with the control.

The main question seems to be: what's the first version of grid we land? Is it a block, or something else?

If we go for a new block, I would not add a responsive toggle. Fixed-width columns are handled by the Columns block, having another place might add confusion. By surfacing child block width controls like Saxon suggests, it might also be possible to accomplish this in a more buildery and flexible way.

(Also worth noting, we will almost certainly implement a generic query editor in the future. #19909 is out of date, but it outlines the value proposition, and suggests a single interface that works across blocks. So with few exceptions, we should avoid per-block responsive implementations that aren't intrinsic.)

A benefit of making it a block & group variation, beyond organically growing to support new features without back compat concerns, is that we could potentially surface this variation picker on the Post Content block, allowing your main canvas to become grid based. The challenge here is to boost our confidence that a new block is the right solution. To do so, I'd keep each feature addition as minimalist as possible, avoid the responsive toggle, and see what patterns our theme devs might be able to accomplish with the new min-width control. A next step could be Saxon's suggestion of child block width controls. The combo might be powerful. But perhaps we should put the new variation behind an experimental toggle until we're sure? Mainly we want to avoid adding a grid block and then removing it again because of something unforeseen.

Another path forward could be absorbing the "Stack on mobile" aspect of the Columns block, perhaps eventually refactoring the whole thing. Conceptually if columns are the main implementation piece of the grid spec, the "Columns" name might be more obvious for the average user. Back compat and complexity might be a blocker for this, I'll refer to you on feasibility.

Thanks for the work!

@apeatling
Copy link
Contributor

Great work @tellthemachines! I found what you have so far quite intuitive, especially as a variation of the group block, it felt like a natural edition in the placeholder and sidebar next to the other layout variations.

I don't have a great deal to add at this point, it made sense to me. I did find myself agreeing with Joen above:

If we go for a new block, I would not add a responsive toggle. Fixed-width columns are handled by the Columns block, having another place might add confusion.

In the sense that even in the group block variation setup here, it's still duplicative of the columns block and could be confusing?

Screenshot 2023-03-15 at 11 25 37 AM

@tellthemachines
Copy link
Contributor Author

Thanks for all the feedback folks!

thinking we add columns range to dimensions panel, either replacing width or in addition to.

The width/height panel won't really work for grid children; the only way we can manipulate size on the actual child is by changing the number of columns it spans. Fill/fixed type behaviour has to be defined on the columns template at the parent level. Let's go with just the columns range for now!

If we wanted to adopt similarish behaviour to the columns block we could either:
reduce number of columns when scaling viewport (like this)
or just reduce to single column (replicate stack on mobile setting)

I think reducing number as viewport (or container) scales is a better approach, given that a frequent complaint about the current behaviour of Columns is that it goes from x to 1 with no middle ground 😄

what if the column number could be treated as "fuzzy" or "explicit" (or something like that), and if it's fuzzy, then it's actually just setting a minimumColumnWidth behind the scenes, rather than an explicit column number — but to the user it would appear as if they're adjusting the number of columns. Might be tricky to pull off, though, as it'd probably involve the UI observing how much space is currently available when the user adjusts the value

That's an interesting idea! It would be tricky to implement. It's probably not an optimum solution for smaller screens though, given if we have any kind of responsive behaviour we couldn't accurately show what a higher number of columns would look like, if that makes sense?

The main question seems to be: what's the first version of grid we land? Is it a block, or something else?

I think the easiest and probably best way to quickly get some real-world use is adding it as a Group block variation.

But perhaps we should put the new variation behind an experimental toggle until we're sure? Mainly we want to avoid adding a grid block and then removing it again because of something unforeseen.

We could use a feature flag, but that would mean less exposure and less ad-hoc testing. The current implementation - especially if we remove the "non-responsive" variation and go with just the "min-width" behaviour for now - is a pretty minimal baseline that will allow us to build in whichever direction we like, so it's unlikely we'll have to undo it later. I might be missing something so would be great to hear other folks thoughts on this!

Another path forward could be absorbing the "Stack on mobile" aspect of the Columns block, perhaps eventually refactoring the whole thing. Conceptually if columns are the main implementation piece of the grid spec, the "Columns" name might be more obvious for the average user.

It would be worth exploring (again!) how Columns could work with grid but due to the nested nature of the block it will likely be complex to implement, so might not be the best starting point for exposing grid-based layouts to users.

An additional thought: I'm pretty excited for Subgrid which is currently being implemented in Chrome. Support for it would be pretty simple to implement on top of this PR: we could add an "inherit" toggle to descendants of grid layouts that would allow them to align with the parent grid.

@SaxonF
Copy link
Contributor

SaxonF commented Mar 16, 2023

The width/height panel won't really work for grid children; the only way we can manipulate size on the actual child is by changing the number of columns it spans. Fill/fixed type behaviour has to be defined on the columns template at the parent level. Let's go with just the columns range for now!

@tellthemachines just to clarify my thoughts here. Column span could be seen as a width unit type (like px) even though behind the scenes it's a separate property. Was thinking something like Width: 4 [columns] but could also just do Columns: 4 instead. I don't feel too strongly either way though.

@tellthemachines
Copy link
Contributor Author

I've reverted the non-responsive option for now.

Small detail, I couldn't click/drag inside the input slider to increment/decrement. We might also want a input+slider combo for this.

It's working for me, though with rem set it seems to go slower than with px. I'll look into adding a range control to it too.

@robglidden
Copy link

Noting that this comment responding to this comment on #49084 mentions it might be good feedback on this PR too.

@tellthemachines
Copy link
Contributor Author

I've added a RangeControl, but am running into semantics and labelling-related issues 😅 I'd appreciate feedback on.

Both UnitControl and RangeControl have the same functionality, so they should have the same label.

We could wrap both these controls in a fieldset and label them with a legend, but does that make sense given that, from a screen reader perspective, they duplicate each other's functionality? The range control is really just a nice to have for mouse users. I wonder if it would be preferable instead to hide it from screen readers with aria-hidden? @alexstine or @joedolson do you have any views on this?

@alexstine
Copy link
Contributor

@tellthemachines Whatever you do, do not use aria-hidden here. The rule for aria-hidden is it cannot be added to any element with implicit tabindex="0" rendered by the HTML itself. For example, adding <button aria-hidden="true" /> creates a problem because the button is still in the tab order but now hidden to screen readers. This is a pattern to avoid.

Thanks.

@joedolson
Copy link
Contributor

Because they control the same functionality, they can have the same label. Different labels are only required if the fields are actually different. The different semantics (type of input) will be conveyed by the control itself, so there's no need to differentiate.

I'll second Alex's comments on aria-hidden, though - using aria-hidden on focusable elements is a poor user experience for screen readers. It's only intended for hiding text nodes.

@andrewserong
Copy link
Contributor

andrewserong commented Mar 20, 2023

We could wrap both these controls in a fieldset and label them with a legend, but does that make sense given that, from a screen reader perspective, they duplicate each other's functionality?

Not sure if it helps (or if it's the right approach), but with the HeightControl component, which pairs a UnitControl with a RangeControl, it uses a fieldset and legend approach here: https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/components/height-control/index.js#L98-L101

If we wind up going in a different direction, though, we could always update the HeightControl, too 🤔

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just took this for another spin (I'm so excited about this PR 😀), and had a couple of questions:

  • Left a comment about whether or not we should prevent columns from overflowing by nesting a min() within the minmax() of the rule, to deal with narrower viewports
  • Quite possibly not a question for this PR, but in a follow-up will we want to add the content justification options here? Though I imagine we'll likely want to try playing around with justify-items for some fun with how child blocks are aligned within their columns?

image

As it stands, just the minimum column width alone does feel like it'd make for a useful MVP to me.

Comment on lines 68 to 72
if ( minimumColumnWidth ) {
rules.push(
`grid-template-columns: repeat(auto-fill, minmax(${ minimumColumnWidth }, 1fr))`
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just playing around with this again, and I noticed that if we set a minimum column width that is greater than the viewport width, that the children will overflow the container:

image

Is it worth trying to add a guardrail to the rule so that the minimum value can never be more than 100%? Would it be possible to nest min() within minmax()? So possibly something like the following:

grid-template-columns: repeat(auto-fill, minmax(min(${ minimumColumnWidth },100%), 1fr))

That seems to work for me locally:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooooh good catch! I'll have a play with it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay, glad it was a simple fix!

@tellthemachines
Copy link
Contributor Author

Thanks for the feedback folks! Yeah, aria-hidden wouldn't work great given the control still needs to be focusable for sighted keyboard users.

I wrapped both controls in a fieldset with a legend for now; it's the same pattern we're using in other places where there's a combo of UnitControl and RangeControl.

I think this is ready for another round! I'm going to go ahead and mark it ready for review, and start looking into adding/updating tests where needed.

@tellthemachines tellthemachines marked this pull request as ready for review March 21, 2023 03:11
@andrewserong andrewserong added [Type] Enhancement A suggestion for improvement. [Block] Group Affects the Group Block (and row, stack and grid variants) labels Mar 22, 2023
Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking very close to me @tellthemachines! 🎉 I left a question about handling the default / placeholder value, and what it may or may not mean for future-proofing. We've had to change default values for the Group and other blocks a couple of times, so just thought it might be worthwhile to think through what the next steps might be in a follow-up if we either wanted to change the default from 12rem or add back in the fixed number of columns.

Also left a tiny nit with spacing between the UnitControl and RangeControl. Other than that, is the last thing to get a final icon for the Grid icon / another design review?

@@ -280,6 +280,37 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
);
}
}
} elseif ( 'grid' === $layout_type ) {
$minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a future proofing question: if minimumColumnWidth isn't set, this assumes a default of 12rem. If we want to enable the control over individual columns again in follow-ups, how will we tell that we shouldn't be outputting 12rem?

By which I mean, what are the trade-offs between using 12rem as an inferred value, versus explicitly defining 12rem within the Grid variation? For example, what if other blocks wished to use a different default minimum column width?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be pretty easy to introduce something like isResponsive again, or any other property that indicates that the grid type is not based on column width (which would always be the default). We'll need a check before outputting the value because the whole template-columns declaration will be different for a static grid, and even if a minimumColumnWidth is set (e.g. if we don't reset it on switching to another grid type) we will only use the value if the grid is of the responsive type (or whatever we want to call it).

I chose 12rem arbitrarily, it could be any other value but we do need to have some default value here or the auto-fill won't work.

If other blocks want to use a different value they can set it when they define the layout type, e.g. layout: { type: 'grid', minimumColumnWidth: '9rem' }.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So (just to make sure I'm following), we're essentially saying, a grid layout with absolutely no other values will default to 12rem minimum column width. For future changes, we're adding additional attributes that will be set, so it'll be easy to determine when to switch off the current logic. And for changing the 12rem default on a block-by-block basis, we provide the default type type value as you mention.

Sounds solid to me! 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the idea is to have a sensible default so you can just add a grid and it'll look ok for the majority of cases? Then progressively add configurability.

packages/block-editor/src/layouts/grid.js Show resolved Hide resolved
*/
function allow_grid_functions_in_styles( $allow_css, $css_test_string ) {
if ( preg_match(
'/^grid-template-columns:\s*repeat\([0-9,a-z-\s\(\)]*\)$/',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me for now, but just wondering what the fix in core will be for it? I suppose we don't need to figure that out right now, but I was curious if it'll just be a matter of adding repeat to this line in core, or if it'll be more complex.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judging by the previous update it should be pretty straightforward.

@tellthemachines
Copy link
Contributor Author

I added a unit test for the new layout type ✅

Would be great to get another round of design feedback! Cc @SaxonF @jasmussen

Comment on lines +76 to +80
// Reason to disable: the extra line breaks added by prettier mess with the unit tests.
// eslint-disable-next-line prettier/prettier
output = `${ appendSelectors( selector ) } { ${ rules.join(
'; '
) }; }`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option (totally feel free to ignore this!), if we don't want to disable prettier on this line could be to perform the output over two lines. So, something like:

Suggested change
// Reason to disable: the extra line breaks added by prettier mess with the unit tests.
// eslint-disable-next-line prettier/prettier
output = `${ appendSelectors( selector ) } { ${ rules.join(
'; '
) }; }`;
output += `${ appendSelectors( selector ) } { `;
output += `${ rules.join( '; ' ) }; }`;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to dig too deeply into it in this PR, but it feels a bit absurd to have prettier formatting multi-line strings at all, because sometimes the spacing is there for a specific reason. Something to look at later perhaps?

Copy link
Contributor

@andrewserong andrewserong Mar 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it feels a bit absurd to have prettier formatting multi-line strings

Totally, and not a blocker at all. This was just in case you didn't want the extra disable in there. I doubt we can really configure prettier here, though, as far as I know there's not a lot of configurability.

Copy link
Contributor

@andrewserong andrewserong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work again @tellthemachines! 🎉 This is all testing nicely for me, and the default values look good, and I like that we've got a good plan for enhancements without boxing ourselves in 👍

This looks like a great place to start for the block / layout type to me. It'd be great to get another round of design feedback as you mention / possibly some more code reviews, but this LGTM! ✨

@SaxonF
Copy link
Contributor

SaxonF commented Mar 24, 2023

Nice work @tellthemachines . Feels like a solid introduction to grid with clear pathways to column count, column span etc :shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Group Affects the Group Block (and row, stack and grid variants) [Feature] Layout Layout block support, its UI controls, and style output. Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Grid Layout type