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

New Component: Stack #5419

Closed
11 tasks done
dzearing opened this issue Jul 2, 2018 · 6 comments · Fixed by #8008
Closed
11 tasks done

New Component: Stack #5419

dzearing opened this issue Jul 2, 2018 · 6 comments · Fixed by #8008

Comments

@dzearing
Copy link
Member

dzearing commented Jul 2, 2018

Component Details

A Stack is a container-type component that abstracts the implementation of a flexbox in order to define the layout of its children components.

Why should we abstract flexbox?

The reason for abstracting flexbox comes from our drive to provide a complete component library, where we wouldn't want for the consumer to need to write additional CSS just to get flexbox functionality. By abstracting flexbox we:

  1. Provide an official Fabric, CSS-less way of getting flexbox functionality into the apps.
  2. Remove some of the mental strain that comes from thinking about the axes when using flexboxes.

Stack properties

Although Stack has a number of different properties, there are three in particular that define the overall layout that the component has:

  • Direction: Refers to whether the stacking of children components is horizontal or vertical. By default the Stack component is vertical, but can be turned horizontal by adding the horizontal property when using the component.
  • Alignment: Refers to how are the children components aligned inside the container. This is controlled via the verticalAlign and horizontalAlign properties. One thing to notice here is that while flexbox containers align always across the cross axis, Stack aims to remove the mental strain involved in this process by making the verticalAlign and horizontalAlign properties always follow the vertical and horizontal axes, respectively, regardless of the direction of the Stack.
  • Spacing: Refers to the space that exists between children components inside the Stack. This is controlled via the gap ad verticalGap properties.

Stack wrapping

Aside from the previously mentioned properties, there is another property called wrap that determines if items overflow the Stack container or wrap around it. The wrap property only works in the direction of the Stack, which means that the children components can still overflow in the perpendicular direction (i.e. in a Vertical Stack, items might overflow horizontally and vice versa).

Stack nesting

Stacks can be nested inside one another in order to be able to configure the layout of the application as desired.

Transition from HorizontalStack and VerticalStack to singular Stack component

Description of the changes

When discussing the promotion of the component from the experiments package into the office-ui-fabric-react package, it was decided that we should change the approach we were using in the experiments package of having two separate components, HorizontalStack and VerticalStack, and instead have a single component Stack with a boolean property horizontal that determines if the stack is horizontal or vertical, with a vertical stack being the default.

This change required modifying existing examples, tests and usage of Stack inside other components throughout the experiments package. The HorizontalStack and VerticalStack pages in the experiments website have also been removed and a Stack page has been added to the office-ui-fabric-react website as part of this change.

Focus areas to test

All the existing tests (snapshots, vr-tests, etc) for HorizontalStack and VerticalStack have been modified to use the singular Stack component and the new component has been tested against all of them to ensure conformance with how the previous components worked.

Component Documentation

Imports

Stack does not make use of other components internally to be constructed.

Exports/ Component Breakdown

Both the Stack and StackItem components are exported, as well as the Stack and StackItem properties defined in Stack.types and StackItem.types respectively.

Intended Package

Initially in @uifabric/experiments while we drive the changes to have the correct api, but with the intention of moving it to office-ui-fabric-react after that is done.

Code mockup/example

Basic Vertical Stack Code Sample

<Stack gap={5}>
   <span>Default vertical stack</span>
   <Stack className={styles.root}>
      <span>Item One</span>
      <span>Item Two</span>
      <span>Item Three</span>
   </Stack>
   <span>Vertical gap between items</span>
   <Stack gap={10} padding={10} className={styles.root}>
      <span>Item One</span>
      <span>Item Two</span>
      <span>Item Three</span>
   </Stack>

   <span>Item alignments</span>
   <Stack gap={5} padding={10} className={styles.root}>
      <Stack.Item align="auto" className={styles.item}>
         <span>Auto-aligned item</span>
      </Stack.Item>
      <Stack.Item align="stretch" className={styles.item}>
         <span>Stretch-aligned item</span>
      </Stack.Item>
      <Stack.Item align="baseline" className={styles.item}>
         <span>Baseline-aligned item</span>
      </Stack.Item>
      <Stack.Item align="start" className={styles.item}>
         <span>Start-aligned item</span>
      </Stack.Item>
      <Stack.Item align="center" className={styles.item}>
         <span>Center-aligned item</span>
      </Stack.Item>
      <Stack.Item align="end" className={styles.item}>
         <span>End-aligned item</span>
      </Stack.Item>
   </Stack>

   <span>Clickable vertical stack</span>
   <Stack onClick={this._onClick} padding={10} className={styles.root}>
      <span>Click inside this box</span>
   </Stack>
</Stack>

image

Basic Horizontal Stack Code Sample

<Stack gap={5}>
   <span>Default horizontal stack</span>
   <Stack horizontal className={styles.root}>
      <span>Item One</span>
      <span>Item Two</span>
      <span>Item Three</span>
   </Stack>

   <span>Horizontal gap between items</span>
   <Stack horizontal gap={10} padding={10} className={styles.root}>
      <span>Item One</span>
      <span>Item Two</span>
      <span>Item Three</span>
   </Stack>

   <span>Item alignments</span>
   <Stack horizontal gap={5} padding={10} className={styles.root} styles={{ root: { height: 100 } }}>
      <Stack.Item align="auto" className={styles.item}>
         <span>Auto-aligned item</span>
      </Stack.Item>
      <Stack.Item align="stretch" className={styles.item}>
         <span>Stretch-aligned item</span>
      </Stack.Item>
      <Stack.Item align="baseline" className={styles.item}>
         <span>Baseline-aligned item</span>
      </Stack.Item>
      <Stack.Item align="start" className={styles.item}>
         <span>Start-aligned item</span>
      </Stack.Item>
      <Stack.Item align="center" className={styles.item}>
         <span>Center-aligned item</span>
      </Stack.Item>
      <Stack.Item align="end" className={styles.item}>
         <span>End-aligned item</span>
      </Stack.Item>
   </Stack>

   <span>Clickable stack</span>
   <Stack horizontal onClick={this._onClick} padding={10} className={styles.root}>
      <span>Click inside this box</span>
   </Stack>
</Stack>

image

Stack Types

IStackItemSlots

Name Type Description
root IHTMLSpanSlot Defines root slot of the component

IStackItemProps

Name Type Default Value Description
as string | React.ReactType<IStackProps> Defines how to render the StackItem
className string Defines a CSS class name used to style the StackItem
grow boolean | number | inherit | initial | unset Defines how much to grow the StackItem in proportion to its siblings
shrink boolean | number | inherit | initial | unset Defines at what ratio should the StackItem shrink to fit the available space
disableShrink boolean false Defines whether the StackItem should be prevented from shrinking.
align auto | stretch | baseline | start | center | end Defines how to align the StackItem along the x-axis (for vertical Stacks) or the y-axis (for horizontal Stacks)
verticalFill boolean true Defines whether the StackItem should take up 100% of the height of its parent

IStackSlots

Name Type Description
root IHTMLDivSlot Defines root slot of the component
inner IHTMLDivSlot Defines a slot that is placed inside the root slot in order to achieve wrapping. Only used when the wrap property is set to true.

IStackProps

Name Type Default Value Description
as string | React.ReactType<IStackProps> Defines how to render the Stack
horizontal boolean false Defines whether to render Stack children horizontally
reversed boolean false Defines whether to render Stack children in the opposite direction (bottom-to-top if it's a vertical Stack and right-to-left if it's a horizontal Stack)
horizontalAlign 'start' | 'flex-start' | 'end' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly' | 'baseline' | 'stretch' Defines how to align Stack children horizontally (along the x-axis)
verticalAlign 'top' | 'bottom' | 'start' | 'flex-start' | 'end' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly' | 'baseline' | 'stretch' Defines how to align Stack children vertically (along the y-axis)
verticalFill boolean Defines whether the Stack should take up 100% of the height of its parent
disableShrink boolean Defines whether Stack children should not shrink to fit the available space
grow boolean | number | 'inherit' | 'initial' | 'unset' Defines how much to grow the Stack in proportion to its siblings
gap number | string Defines the spacing between Stack children
maxWidth number | string Defines the maximum width that the Stack can take
maxHeight number | string Defines the maximum height that the Stack can take
padding number | string Defines the inner padding of the Stack
wrap boolean false Defines whether Stack children should wrap onto multiple rows or columns when they are about to overflow the size of the Stack

Component Ownership

  • @kkjeer who initially created the component
  • @khmakoto who is promoting the component from @uifabric/experiments to office-ui-fabric-react

Deadlines

We are aiming for the component to be promoted from @uifabric/experiments to office-ui-fabric-react in February 2019.

Steps

  • Themable (Component.base/Component.styles)
  • Unit tests
  • Visual tests
  • Documentation and examples
  • Keyboard Accessible
  • High Constrast Support
  • RTL Support
  • Design Review
  • API review
  • Public Preview
  • Ready for Publishing
@micahgodbolt micahgodbolt added this to the August 2018 milestone Jul 30, 2018
@micahgodbolt micahgodbolt mentioned this issue Jul 31, 2018
30 tasks
@micahgodbolt micahgodbolt removed this from the August 2018 milestone Aug 6, 2018
@micahgodbolt
Copy link
Member

change default direction to vertical, add a horizontal props (if this hasn't already been done).

@micahgodbolt
Copy link
Member

@khmakoto sorry...didn't mean to say close this, but update it and have your PR close it via updating the "Fixes #0000" part

@msft-github-bot
Copy link
Contributor

🎉This issue was addressed in #8008, which has now been successfully released as @uifabric/[email protected].:tada:

Handy links:

@msft-github-bot
Copy link
Contributor

🎉This issue was addressed in #8008, which has now been successfully released as [email protected].:tada:

Handy links:

@msft-github-bot
Copy link
Contributor

🎉This issue was addressed in #8008, which has now been successfully released as @uifabric/[email protected].:tada:

Handy links:

@msft-github-bot
Copy link
Contributor

🎉This issue was addressed in #8008, which has now been successfully released as @uifabric/[email protected].:tada:

Handy links:

@microsoft microsoft locked as resolved and limited conversation to collaborators Aug 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.