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

Block Editor: Implement a responsive grid mode for InnerBlocks and a basic grid block that leverages it. #18600

Closed
wants to merge 3 commits into from

Conversation

epiqueras
Copy link
Contributor

Description

This PR seeks to introduce an experimental responsive grid mode for InnerBlocks. This mode could be used to power a myriad of grid based blocks, where each one tunes the UI to what is most appropriate for each context.

It can be enabled using a new __experimentalGridMode boolean prop on InnerBlocks and InnerBlocks.Content. When enabled, it will render the inner blocks in a responsive, min-width breakpoint based grid layout.

In the editor you can toggle between breakpoints, add, remove, move, and resize blocks, etc. The layouts will be persisted as an attribute of the parent block. In the front end, the saved layouts are rendered using a combination of media queries and CSS grid.

There is a lot more potential for customization that I felt would have made this PR too expansive, but I imagine that in the future we could even support customizing things like the number of columns and the row height, per breakpoint, and even the breakpoints themselves.

It's also worth noting that the interactions are far from perfect, but I think it's usable enough to share now.

The main library used for the editor portion of this PR is a somewhat low level grid editing library used by lots of large projects, like AWS, HubSpot, Monday, etc.

https://github.com/STRML/react-grid-layout#projects-using-react-grid-layout

How has this been tested?

It hasn't been thoroughly tested yet.

Screenshots

https://youtu.be/1CacV2MYF_A

Demo Video

Types of Changes

New Feature: InnerBlocks now supports a grid mode for building grid based layouts and there is a new basic grid block that leverages it.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR. .

@epiqueras epiqueras added [Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P [Package] Block editor /packages/block-editor labels Nov 19, 2019
@epiqueras epiqueras added this to the Future milestone Nov 19, 2019
@epiqueras epiqueras self-assigned this Nov 19, 2019
@aristath
Copy link
Member

aristath commented Nov 19, 2019

Amazing... I started working on the exact same thing last week 'cause I needed it, it's great to see this in core ❤️ ❤️

The only thing missing from that implementation is the ability to edit the width of columns and height of rows. If that gets implemented too, then this block could be used as a super-block for the site-layout in templates

@epiqueras
Copy link
Contributor Author

Thanks! 😄

Yeah, that's the idea.

There is a lot more potential for customization that I felt would have made this PR too expansive, but I imagine that in the future we could even support customizing things like the number of columns and the row height, per breakpoint, and even the breakpoints themselves.

@aduth
Copy link
Member

aduth commented Nov 22, 2019

A note in passing, as I was testing this very briefly:

I see horizontal scroll in a newly added block:

image

(Aside: Might help to test with Show scroll bars: Always)

@aristath
Copy link
Member

I've been thinking a lot about this one lately...
A "grid" block like this one would be an essential step towards full-site editing. In fact I'd say it's probably the most essential part in allowing theme-developers to start building something really usable.
In order for this to be really useful though, it would have to allow the following:

  • Setting the width of grid columns (grid-template-columns). Having everything set to 1fr would not allow for layouts like for example a 300px-wide sidebar, or a side-header that is 20em wide.
  • Setting the height of rows (grid-template-rows). This would allow users to define that their header is 200px tall, and it won't grow taller on pages with limited content.
  • Multiple grids should be allowed nested. This way they can have a "global" grid with just 3 rows for example, and a separate grid inside the 1st row where they'll be able to build their header (which will usually need things like branding, navigation, search, and whatever else users deem necessary for their specific scenario).

STRML is probably the best script I've found so far that can help us achieve these goals, it is used by several large projects and is well-maintained. We could build something custom, but I really can't think of a good reason why we would do something like that instead of using a well-established library.


The only thing I question in this implementation is the "responsive" part. "Responsive" doesn't necessarily mean "multiple breakpoints"... Multiple breakpoints will only make it harder for people to build something if they have to do multiple steps. It could be as simple as a single breakpoint (big screen/small screen), switching from display:grid to flex or even block - in which case the blocks become stacked. The "stacked" thing is probably the simplest experience for mobile users where horizontal space is limited. In that case, the only thing that users would have to decide is what the breakpoint for the grid/stacked change will be, or it could be defined in the theme itself.

@epiqueras
Copy link
Contributor Author

epiqueras commented Dec 27, 2019 via email

@aristath
Copy link
Member

aristath commented Dec 28, 2019

There are too many variables for mobile/tablet/desktop... For example my theme may have a native-looking mobile menu on the bottom where the home/menu/search buttons go. That would require a "hide on mobile" switch on each block... adding a switch like that however on blocks because "what if my theme has feature X" would lead to an extremely cluttered UI making things more difficult to edit.
Yes, I may want my sidebar to collapse only on a specific breakpoint.
But now that I think about this, what if the breakpoint was per-grid?
So for example I can define a breakpoint for my global grid (which has the sidebar) @800px, and I can set the breakpoint for my header grid @60em, while I leave the footer breakpoint blank - which will fallback to the theme default.
This way with nested grid users can achieve whatever result they may need. If they want something simple they just don't bother with breakpoints, and it just collapses to stacked on smaller screens. If they want to fine-tune things they can do it on infinite levels by properly structuring their templates and defining breakpoints on their grids.

@epiqueras
Copy link
Contributor Author

epiqueras commented Dec 28, 2019 via email

@aristath
Copy link
Member

We would also need an option to completely hide a grid at the breakpoint.
For cases where you want to not display sections instead of collapsing them.

Makes perfect sense 👍

@aristath
Copy link
Member

The only thing that troubles me is the technical aspect of this: In order to make breakpoints work like this, all grids should have an ID so they can be targeted by our styles. So in case the user hasn't defined an ID manually, perhaps a unique ID should be generated?
If we have <div class="wp-block-grid" id="foo"> then we'll be able to target it by adding an inline style with something like

<style>
/* 600px is the user-defined breakpoint - or default */
@media screen and (max-width: 600px) {
  /* user chose to hide the grid on mobile */
  #foo { display: none; }
}
</style>

Without an ID or some other unique selector we won't be able to target a specific grid to apply our styles

@epiqueras
Copy link
Contributor Author

epiqueras commented Dec 28, 2019 via email

@aristath
Copy link
Member

I just checked out the branch and yeah, you're right, it's all already implemented 👍
I was avoiding git-clone & npm install 'cause I'm on a metered connection and the data cost is huge for these builds. Anyway, I did now so I can check this one more in-depth.
So the real question here now is where do we put the column-width & row-height controls? That is the main UI issue from my perspective... 🤔

@epiqueras
Copy link
Contributor Author

epiqueras commented Dec 28, 2019 via email

@aristath aristath mentioned this pull request Dec 30, 2019
@mapk mapk added the Needs Design Feedback Needs general design feedback. label Dec 30, 2019
@mapk
Copy link
Contributor

mapk commented Jan 9, 2020

If this becomes a way for users to create new templates, as noted as a possibility here: #19254, I'd love to be able to do something like this with it.

grid 2020-01-08 16_42_52

I begin laying out the basic structure of the page while planning for template-parts; Header, Content, Footer. I then try adding Sidebars, etc.

These features become a necessity:

  1. Add/Remove grid-items.
  2. Able to move them around freely without being adjacent to other grid-items.
  3. Able to drop them below or above particular rows of grid-items.

The example is from: https://strml.github.io/react-grid-layout/examples/6-dynamic-add-remove.html

@epiqueras
Copy link
Contributor Author

That can all be done in this implementation.

@epiqueras
Copy link
Contributor Author

Closing in favor of #20000.

@ockham
Copy link
Contributor

ockham commented Feb 25, 2020

Closing for real, since #18600 (comment) doesn't seem to have done the trick 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P Needs Design Feedback Needs general design feedback. [Package] Block editor /packages/block-editor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants