liferay / clay

A web implementation of the Lexicon Experience Language
http://clayui.com
Other
207 stars 480 forks source link

Layout util components #2421

Closed bryceosterhaus closed 4 years ago

bryceosterhaus commented 5 years ago

We might want to look into creating some helper components for people that are creating layouts. I am thinking something like containers, rows, columns, sheets, etc.

matuzalemsteles commented 5 years ago

I've been thinking about this, now I don't know what value we can have with them, I imagine these components will be very simple and just a markup rendering. do you have any thoughts?

bryceosterhaus commented 5 years ago

Yeah it would likely just render markup, but I think we could possibly provide a few utils that make managing a layout easier. I haven't fully thought through it, it just came to mind the other day when I was creating the demos.

matuzalemsteles commented 5 years ago

Yeah it would likely just render markup, but I think we could possibly provide a few utils that make managing a layout easier. I haven't fully thought through it, it just came to mind the other day when I was creating the demos.

Ok, no. We can think about it better later. Even though we don't deliver this to the release of v3.0.0 we can add it at some point in 3.x.

jbalsas commented 4 years ago

I've added this to the https://github.com/liferay/clay/milestone/19

matuzalemsteles commented 4 years ago

hey @jbalsas as comment from https://github.com/liferay/clay/issues/3082#issuecomment-606457343. I will leave some ideas that I have about this.

I follow a design system from Seek that Mark Dalgleish talks a lot about where he works, he presented some of his characteristics and it is very interesting how they approached the creation of primitive components only. They did a great job with the harmonization of API's for the Layout components, in case you are curious https://seek-oss.github.io/braid-design-system/foundations/layout.

I think the main idea that we should take with the creation of these Layout components is also the primitive ones, we can offer Rows, Columns with APIs that allow people to achieve different spacing and layout flexibility.

A component that caught my attention is the <Stack /> (https://seek-oss.github.io/braid-design-system/components/Stack), it only handles components vertically and offers API's to handle with the blank spaces between them, this is very interesting because it replaces the use of Row and offers layout flexibility. I like this design style, instead of describing it a lot to assemble the layout, the component does a bit of magic underneath but still adding a lot of value and covering cases of layouts that have different spacing.

<Stack space="gutter">
  <Placeholder height={40} />
  <Placeholder height={40} />
  <Placeholder height={40} />
</Stack>

I think this can help to solve a lot of problems in some layouts, the spacing between components in vertical and horizontal (if I am not mistaken I saw @drakonux saying that they have a space rule every 8px, correct if I am wrong.). These are some shallow thoughts that I have now, I know that there are some other challenges, but in the components in React we can do something to make it all simple and configurable, this may seem more like a high level component.

Ping @eduardoallegrini and @marcoscv-work if that helps.

edalgrin commented 4 years ago

I took a look at the design system and I think it's great, and even if it's too soon to decide what we need (since we don't know for sure what we have yet) I will link your comment in the results of the spike we are working on.

My only concern is that it seems to have some limits, for example: what happens if we need different spaces between the elements inside the container? (but again, I didn't read the whole documentation :) )

matuzalemsteles commented 4 years ago

My only concern is that it seems to have some limits, for example: what happens if we need different spaces between the elements inside the container? (but again, I didn't read the whole documentation :))

Hey @eduardoallegrini yeah, I think this is one of the main problems that we may have, I think it will be difficult to correct this, even if we have much smaller spacing patterns it will still be a problem in cases when some layout does not respect this. I think the best thing to do is for Lexicon to impose a spacing rule every n px... we can control these spacing with the addition of class utils.

bryceosterhaus commented 4 years ago

I spent some time looking into this today and I really like the approach that Seek went with. At first I was thinking we might go the route of just implementing low-level components from bootstraps layout system, but I think that might be a bit too granular. If we go the approach of Seek's design system, it would give us more control in how we recommend that the layout flows.

I think if we could start off with three components for this and see how it goes. I am thinking of adopting similar components of Stack, Tiles, and ContentBlock from seek and using a similar API pattern for layouts. And then if we can address our demos and these layouts with those components, I think we could consider that a success.

Thoughts on that?

jbalsas commented 4 years ago

Hey @bryceosterhaus!

At first I was thinking we might go the route of just implementing low-level components from bootstraps layout system, but I think that might be a bit too granular

I think this is the expectation with low-level components and the philosophy we set out to follow in Clay. As with everything else, the failure in delivering low-level and granular components results in developers using whatever escape hatch they can find (directly bootstrap's html in this case) when the higher-level abstractions don't leave room to wiggle.

I am thinking of adopting similar components of Stack, Tiles, and ContentBlock

I think that by adding Columns and Inline to the mix we might just get away with it. Based on a quick exploration, I'd say these more or less hold true:

Seek Bootstrap
Stack Container
Inline Row
Columns Col
Tiles ??
ContentBlock ??

So, we should be able to create any existing layout with that combination of components.

And then if we can address our demos and these layouts with those components, I think we could consider that a success

A success indeed ☺️ ! On top of that, as we've been doing, I'd like to make sure these actually cover real implementations, so a tour through DXP's JSPs and JSX components and layouts would very much help in having a clearer picture of how are we composing layouts and what we might need in the future.

@drakonux, @laugardie, thoughts on this? @eduardoallegrini, @marcoscv-work, @matuzalemsteles?

wincent commented 4 years ago

I'd be sad if we adopted completely different terminology ("Stack" etc) in the Clay React components from what we just started rolling out for taglibs in liferay-portal (clay:container, clay:row, clay:col). It would be suboptimal if we had to ask developers using the two flavors of Clay layout components to learn two different naming systems and conceptual models.

marcoscv-work commented 4 years ago

I think to use more common vocabulary closer to what designers use sounds great. But on the other hand, I'm not sure if this really helps developers, or instead of that, we would confuse them.

My concern is that in case of using a new grid naming probably most of the developers who want to work with our grid would need to figure out our grid naming and match them with something they already know, what probably will be 'container' 'row' 'col'.

drakonux commented 4 years ago

Hello everyone,

Well from my point of view, the naming should be oriented to the users that are going to consume this information. In this case, front-end developers isn't it?.

However, what's the intent of all these changes? Having that defined it will help you to describe where you want to go...

Thus, you should consider the direction of all these changes. For example, if developers have been working for years using Bootstrap, they are going to be accustomed to them... instead of creating new names that would bring like a new or refresh stage of the project.

Said this, as a designer to chose explicit names is always better because we can figure out the purpose of the tag/object just reading. So a stack will stack things within. Instead, a container is just a thing that contains things but it doesn't give more information about how the content its arranged or behaves.

In my opinion, trying to not think so much about technology constraints, the most basic containers in interfaces are:

matuzalemsteles commented 4 years ago

Yeah, a few thoughts: I think that delivering the low-level layout components may not be of much value because they will just be wrappers over simple markups for cols and containers, something that developers can do very well with just a simple HTML...

I think that's why I like the Stack approach because it is different from having a component for Column, Row and Container, it looks similar to them but it is much more powerful because it is focused on the vertical spacing of its child components, this covers common white space problems in layouts where they are very important. I think we should treat these two as different things from the Column, Row and Container terminology. The purpose of each one is different and we must make this clear, to show developers how to use and understand this new way we have to reinforce in our documentation if possible make a blog post on Clay showing this new difference and that maybe you can even use together.

For this beginning of components for the Layout family I think we can go with these components of Stack... as Bryce and Chema commented and in a future we can add components for container, row and col just like a way for developers to more use our components...

An addendum to the use of Stack: I like this approach because it helps to solve white space props problems in the layout, as I had said the use of space would be equivalent to the spacing rules that Lexicon allows for each (8px) , that would be difficult to achieve in larger numbers but we can follow a linear value and then always duplicate the next one. I see a similar approach in Tailwind with its spacing utils... and I still see value in container, row and col it has its cases but it has some gaps I think Stack helps with that.

wincent commented 4 years ago

Yeah, a few thoughts: I think that delivering the low-level layout components may not be of much value because they will just be wrappers over simple markups for cols and containers, something that developers can do very well with just a simple HTML...

I think that's why I like the Stack approach because it is different from having a component for Column, Row and Container

So this is pretty much exactly the question that was discussed extensively in the analysis of currently used layout strategies in DXP and the resulting proposal for new Clay taglibs.

It would be very odd if we repeated exactly the same discussion but reached the opposite conclusion, or a substantially different one.

That's not to say that we can't discuss it further, or again, just that it would be useful if we all had that recent context in mind when we discuss it here. Personally, I actually like non-Bootstrap abstractions for layout and have used them in other contexts, but I like consistency across two "sibling" implementations (Clay layout taglibs and Clay layout React components) more.

Your argument that a different abstraction could add value is right: but I would think that before getting to that we should aim to have parity between taglib and React implementations (ie. containers, rows, columns in both) and then, if we can prove the value of another layer on top of that, we implement it in both places.

jbalsas commented 4 years ago

One key point to note is that we can't do for JSP tags what is proposed for Stack, because we can't easily parse the inner HTML to distribute direct children inside nested rows/cols...

A possible escape hatch, even though not exactly what we all want would be to have those same basic components Container, Row, Col... and then use them to build the higher level abstractions Stack...

At the expense of a bigger API surface and some lost symmetry, React devs would be able to pick to stay closer to the technology and JSPs or closer to the design language depending on their needs...

matuzalemsteles commented 4 years ago

So this is pretty much exactly the question that was discussed extensively in the analysis of currently used layout strategies in DXP and the resulting proposal for new Clay taglibs.

It would be very odd if we repeated exactly the same discussion but reached the opposite conclusion, or a substantially different one.

Yeah I'm aware of that, I read the documents but what I saw is that we are trying to solve problems more focused on taglib or kill the old taglibs. A wish: If I could I would kill the taglibs 😛...

An important point: maybe the same developers who use taglibs will not be the same ones who are developing in React, of course there are some developers who are working on both, but we agree that most of the time he will spend is in React.

bryceosterhaus commented 4 years ago

So sounds like we want to offer both approaches of low-level bootstrap centric components and OOTB high-level layout structures(similar to Seeks implementaion).

Low-level would be consistent and uniform with the taglibs and bootstrap. This would include row, col, container, etc, named something like ClayLayout.Row.

And then additionally the more opinionated high-level components would center more on design based layouts, similar to what @drakonux brought up. These would provide simple OOTB layout and structure without having to think in terms of col-x in bootstraps definition. I would imagine that these high-level components would be used more heavily in a react app rather than via jsp.

As for naming, I like how @drakonux said it

chose explicit names is always better because we can figure out the purpose of the tag/object just reading. So a stack will stack things within. Instead, a container is just a thing that contains things but it doesn't give more information about how the content its arranged or behaves.

Now I'm not quite sure what the exact names will be, but I think its a good guide for naming our high-level layouts.

I think this solution addresses most of the concerns brought up here. Any concerns that I missed?

TLDR; Create both low-level(based of bootstrap) and high-level components(opinionated layouts named for its purpose).

marcoscv-work commented 4 years ago

When we speak about Design (I really love it) is really important the abstractions because it has to be abstracted from the development and its vocabulary, but speaking about development I still not having clear the improvement of using abstractions for technical layouts.

We already have some simpler grids in Clay like autofit, and if everything go-ahead I think the result will be really messed, for example:

.container .row .autofit-row

Can be considerer Stack, in fact, even a .col-12 is a Stack. Why? because "Stack" speaks about the behavior of the block. To make it more clear by using markup:

<div class="col-12 col-sm-3">1</div>
<div class="col-12 col-sm">2</div>

In this example, some people could interpret that: 1 and 2 are a Stack in mobile, but "Wraps" on desktop. In the case of autofit float is even more difficult to understand because with it we can merge float and flex behavior: https://clayui.com/docs/css/utilities/autofit.html#float

All of these disagreements are because we have a lot of different ways to create a box, stack, or wrap behavior in CSS, much of them with the same CSS component or CSS class name.

From my point of view, those languages are not directly compatible. :-(

bryceosterhaus commented 4 years ago

initial idea for the low-level components. Did I miss anything? https://github.com/liferay/clay/pull/3204

jbalsas commented 4 years ago

So, basically this boils down to staying true to our Philosophy

We are delivering Clay as a Multi-Layered API library: low-level, high-level and pure html(@clayui/css). Each approach has its purposes of use:

low-level - Basic building blocks to provide flexibility so that you can customize and create high level components. high-level - Highly specific component that tend to cover only specific use cases, limiting their flexibility.

With low-level, devs can generate any layout thrown at them regardless of its adherence to rules. Container, Row, Col and other basic components we have fit perfectly fine here.

One key aspect of these is that they still provide a small abstraction. We're right now using Bootstrap (.container-fluid), but the only way we can push to get rid of it is if we have more usages of ClayLayout.Container than direct div class="container-fluid". Controlling the abstraction makes it easier for us to change the underlying implementation without affecting our users too much (at least on paper).

With high-level we provide a no-brainer to-go solution for the most common cases. We decide on its implementation, so <Stack> is just but one realization of all the possibilities that @marcoscv-work mentions. That is totally fine. We should make sure the component generates our most common use case so the low-level escape hatch only needs to be used occasionally.

bryceosterhaus commented 4 years ago

added at https://github.com/liferay/clay/pull/3204