WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.46k stars 4.18k forks source link

Layout components: standardize API approach #43085

Open ciampo opened 2 years ago

ciampo commented 2 years ago

Context

This issue applies to layout-based components in the @wordpress/components package:

After a couple of recent conversation around these layout components (example, example), I had a look at the state of layout components, here's a few observations:

Solution(s) proposed

Grid and Flex as low-level layout components

One potential solution is to treat Flex and Grid as low-level components, and make sure that they only expose low-level props that are named exactly like the CSS properties.

Pros of this approach:

Cons of this approach:

My opinion

Personally, I am 100% convinced that lower-level and higher-level props should not be exposed within the same component. But I'm not convinced that we should be exposing components that merely expose CSS props via React props either, as it feels to me a poor tradeoff (arbitrary decisions, potentially high maintenance, but low convenience as the consumer may as well just write CSS directly).

A potential solution could be to expose only high-level layout components that can be used to cover the majority of the cases: HStack and VStack already exist, and I believe that they could cover 99% of cases where flexbox is needed (for more complex needs, the consumer may directly implement they custom layout). We could think about creating similar high-level components for the CSS Grid layout?

More in general, as we rework these components, regardless of the solution adopted, we should:

ciampo commented 2 years ago

cc @mirka @chad1008 and a few devs who have been recently working often with the @wordpress/components package @aaronrobertshaw @andrewserong @talldan @ntsekouras

aaronrobertshaw commented 2 years ago

Thanks for putting this issue together here along with your thoughtful analysis. You make some great points.

Personally, I am 100% convinced that lower-level and higher-level props should not be exposed within the same component.

Agreed.

But I'm not convinced that we should be exposing components that merely expose CSS props via React props either

Same. Further to the list of concerns raised, another small con might be given the low convenience factor, we'd get a real mix of approaches using the low-level component or DIY. Could this impede defining a best practice or lead to greater potential for styling inconsistencies?

A potential solution could be to expose only high-level layout components that can be used to cover the majority of the cases

For the cases not covered, would there be any benefit to providing some style mixins to achieve other layouts that might not warrant a dedicated component?

We could think about creating similar high-level components for the CSS Grid layout?

I'd like to see us explore some high-level grid components. Happy to help here if we all decide to go down this path.

mirka commented 2 years ago

A potential solution could be to expose only high-level layout components that can be used to cover the majority of the cases: HStack and VStack already exist, and I believe that they could cover 99% of cases where flexbox is needed (for more complex needs, the consumer may directly implement they custom layout)

I like this. There are multiple times where I've reached for Flex when I could've just used HStack/VStack, because my brain just instinctively thought "flex" 🙈 I don't think I've ever actually needed Flex.

We could think about creating similar high-level components for the CSS Grid layout?

In this vein, as I work on #39358 I'm wondering if we should have a high-level layout component specifically for sidebar controls. It would be nice to have an easy way to maintain layout consistency between ToolsPanel, Global Styles, and custom Inspector controls injected by blocks.

ciampo commented 2 years ago

Thank you for your replies, @aaronrobertshaw and @mirka ! It looks like we may be converging towards this proposed solution:

A potential solution could be to expose only high-level layout components that can be used to cover the majority of the cases: HStack and VStack already exist, and I believe that they could cover 99% of cases where a flexbox layout is needed (for more complex needs, the consumer may directly implement they custom layout). We could think about creating similar high-level components for the CSS Grid layout?

I'll try to answer to the remaining questions that you both asked.

@aaronrobertshaw:

Further to the list of concerns raised, another small con might be given the low convenience factor, we'd get a real mix of approaches using the low-level component or DIY. Could this impede defining a best practice or lead to greater potential for styling inconsistencies?

I believe that's a risk that is there with or without our low-level components, unfortunately — and it's also something that would happen outside of the components package. But if we believe that our set of high-level components would cover the majority of use cases, then hopefully that will be already a good start.

For the cases not covered, would there be any benefit to providing some style mixins to achieve other layouts that might not warrant a dedicated component?

I'm not sure — after all, if a preset "high level" component doesn't cut it, there's a chance that mixins won't either. With regards to which high-level components we should publish (and which properties they offer), I would start with a small set of components / features, ad add more components/features as we encounter layout "challenge" that are frequent enough.

I'd like to see us explore some high-level grid components. Happy to help here if we all decide to go down this path.

Absolutely! I think a good start may be to go through the current usage of Grid and Flex:

@mirka:

In this vein, as I work on https://github.com/WordPress/gutenberg/issues/39358 I'm wondering if we should have a high-level layout component specifically for sidebar controls. It would be nice to have an easy way to maintain layout consistency between ToolsPanel, Global Styles, and custom Inspector controls injected by blocks.

I'd be very interested to see what such a high-level component may look like

andrewserong commented 2 years ago

Apologies for the late reply, and thanks for the discussion here!

I often find it harder to use these components than to write CSS styles myself

I've found this working with Flex, too, and also agree that exposing the lower and higher level props in the one component creates a lot of confusion.

It looks like we may be converging towards this proposed solution:

Consolidating around a few high level components sounds good to me. For cases where these high level components aren't appropriate for someone's use case, would we then encourage folks to use their own flex or grid CSS styling particular to the component they're writing (perhaps attached to View components) over using Flex directly?

ciampo commented 2 years ago

would we then encourage folks to use their own flex or grid CSS styling particular to the component they're writing (perhaps attached to View components) over using Flex directly?

I think so, mainly because (as explained more in details above) that currently using Flex doesn't really bring any advantages over using straight CSS props (although this is not yet a decision set in stone and we should be assessing all what's been discussed in details)

ciampo commented 1 month ago

In the context of https://github.com/WordPress/gutenberg/issues/59418, I'd like to resume this conversation.

Talking to @mirka , we feel that Flex and Grid are not a useful abstraction to maintain, given how CSS flexbox and grid layouts have now gotten wide browser support.

Regarding HStack and VStack, we still think that they could be useful utilities to keep around, but we see issues with their API layers:

For this reason, we're considering to deprecate HStack and VStack and replace them with a new version.

While we're in the process, we're also considering deprecating Spacer, as it offers little value and has issues with its APIs similar to the ones described above for HStack and VStack.

Finally, we don't see much of a need for ZStack, and therefore we're considering deprecating it without a replacement.


Proposal recap:

(cc @WordPress/gutenberg-components )