wave icon indicating copy to clipboard operation
wave copied to clipboard

New component: Stack

Open JanHamara opened this issue 2 years ago • 9 comments

Describe the feature you'd like

Add a <Spacer> component to Wave DS.

Screenshot 2022-06-08 at 16 17 37

We have quite a lot of cases where we:

  • apply margins to non layout-related components
  • use component like <Box> from Wave only to apply margin to it
  • or even define a styled-component just to apply a margin to it, such as in some of the following examples:

In BOMT Screenshot 2022-06-08 at 16 12 53

In some recent PR Screenshot 2022-06-08 at 15 40 38

There is also a nice article, that goes more in depth about why it's better to use Spacer component instead of margin in React apps here


Also <Spacer> is a common layout category component in top-level libraries like Material UI, Chakra UI, Elastic UI, etc.

Elastic UI: https://elastic.github.io/eui/#/layout/spacer NextUI: https://nextui.org/docs/layout/spacer

Chakra UI and Material UI integrate <Spacer> component directly as part of the <Stack> component, whose concept is explained in section below.

Also our awesome @rafael-sepeda has already created a Spacing component for Figma here 🚀 : https://www.figma.com/community/file/1053608171352121792 (So I guess we could say, we already have specs)


Describe alternatives you've considered

<Stack> component

Another option (personally I would suggest to add this as a separate feature request from the <Spacer>) would be to follow the example of Material UI, Chakra UI, etc. and add a <Stack> component to Wave. However, I would keep <Spacer> component as separate layout component as well, firstly we would use it in integration of <Stack> component, but also it can be applicable in cases where we deal with just a single margin, not a stack of spaced items.

So what is <Stack> component

I will just link Chakra UI's Stack component here, and their description, because I guess it's the best I found 😄

Stack is a layout component that makes it easy to stack elements together and apply a space between them. It uses a modified version of the CSS lobotomized owl selector to add spacing between its children.

Spacer: https://chakra-ui.com/docs/components/layout/stack

JanHamara avatar Jun 08 '22 14:06 JanHamara

@JanHamara I was thinking that we already have a spacer https://wave.free-now.com/essentials/spaces https://github.com/freenowtech/wave/tree/main/src/essentials/Spaces

The ones that you show in the example are based on the values from the code. Or you want to create something different?

rafael-sepeda avatar Jun 09 '22 07:06 rafael-sepeda

Hello @rafael-sepeda , yes this PR is about something different, about a component not spacing values :)

I am aware that we have Spaces, but those are spacing values in the theme (as stored in /essentials), not a component that renders this spacing separately from its surrounding neighbour components.

At the moment, we can apply those Spaces from essentials somewhere via margins or even use them for padding values, for example:

// some component that defines its offset in layout from neighbouring elements with margins <Box mt={Spaces[1]} mb={Spaces[3]} >

What I describe in this issue would be a layout component (like this one), that can render that spacing, and that is its only responsibility. (It's goal also being to remove need for solutions, that are described in 3 bullet points at the top of issue)

JanHamara avatar Jun 09 '22 08:06 JanHamara

@JanHamara cool. Sounds good to me! In Figma we have a very simple documentation for the spacing component that we use in the design https://www.figma.com/file/dTefUItBx5bfbxcCcMzMXm/Wave-DS?node-id=202%3A0

rafael-sepeda avatar Jun 09 '22 09:06 rafael-sepeda

I am not sure how much value this will bring. @JanHamara can you chalk out what you would expect the Spacer component's API to look like, and what its advantages are over the current approach? Alternatively, can you also define what the shortcomings of the current approach are? I feel that these would help me assess the usability a bit better.

lloydaf avatar Jun 09 '22 15:06 lloydaf

We need to prepare some examples

rafael-sepeda avatar Jun 16 '22 09:06 rafael-sepeda

https://www.figma.com/file/r0DH6nFNBKGxpDjWhBo5tU/Stacks-vs-Spacers?node-id=0%3A1

rafael-sepeda avatar Jun 30 '22 09:06 rafael-sepeda

Updated issue to New component: Stack, as we've moved to decision to test implementing Stack, rather than Spacer, as it makes much more sense logically in terms of how we setup our layouts in our Figma designs..

JanHamara avatar Jun 30 '22 09:06 JanHamara

POC: Spacer usage demonstration: Recreate UI layout of BOMT booking information page (with topbar and header)


Codesandbox: https://codesandbox.io/s/bomt-stack-layout-forked-ymybld

The goal of this sandbox is to demonstrate, how you can build out any UI layout using just two layout components (or one in fact) - a Stack component: HStack (horizontal stack) and VStack (vertical stack)


Introduction to PoC solution

Stack as name quite clearly indicates is just a stack of elements, a component that stacks your elements using the Flexbox model in either a horizontal or vertical direction, and applies an optional gap (via gap prop) between these elements.

In addition to setting up spacing between the elements, Stack component also offers strong alignment capabilities by exposing justify (justifyContent) and align (alignItems) props for adjusting the alignment and distribution of the items in the UI, as according to Flexbox model capabilities.

As each UI layout can be described / modelled as a set of nested stacks, the Stack component would not only allow us to delegate layout responsibilities to a single component (while still having the freedom to use other strategies), but would also give more semantic meaning to codebase, as you would be able to be predict how UI builds out, just by reading the code.


A simple visual example

example


Other advantages of having Stack component available for building out layouts:

  • Stack uses a modified version of the CSS lobotomized owl selector to add spacing between its children -> (https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/).
  • Layouts build with stack eliminate the need to use margins for laying out components -> and margins break the isolation of components -> https://javascript.plainenglish.io/stop-using-margin-use-spacer-component-instead-953d9b2dbacc
  • Stacks allow us to build out whole UI using standard best-practices -> using CSS 3 web layout model - Flexbox
  • using Flexbox method is a common go-to strategy of top-level libraries for setting space distribution between items in an interface as well as for using powerful alignment capabilities
  • we already have a Stack component for our designs in Figma, so we can align our design system with it on Wave side, without need for new specs

Conclusion So far, we have been using various mixed strategies for setting up layouts in our UI templates:

  • margins and paddings (that break isolation of components and single-responsibility principle)
  • defining new styled-components over and over to apply flexbox model in very specific situations (lack of reusability)
  • setting bottom and top margins for offset between components (in a visual bug-prone way)
  • mixing up strategies for vertical alignment (margin: auto, flexbox, text-align, etc.)

With Spacer, we can have all these layout and alignment capabilities in a simple yet powerful layout component with two flow directions (vertical / horizontal) and a couple of alignment & spacing props (justify / align / gap) that can setup any layout that you need.

JanHamara avatar Jul 14 '22 11:07 JanHamara

@JanHamara could you update us with the key takeaways from the last demo/debating session? Thanks!

arturmiglio avatar Jul 25 '22 10:07 arturmiglio