Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

feat: Flex component #802

Merged
merged 47 commits into from
Feb 8, 2019
Merged

feat: Flex component #802

merged 47 commits into from
Feb 8, 2019

Conversation

kuzhelov
Copy link
Contributor

@kuzhelov kuzhelov commented Jan 30, 2019

Principles

  • minimal markup necessary
  • readable markup (visual effect should be inferable by reading the markup)
  • minimal set of props in vocabulary, with large coverage of use cases
  • no props with conflicting effects
  • no leaky abstractions
  • restricted set of size values (for gap, size, padding props) that should follow foreseen approach to design tokens' names

Layout example sources used

Important cases to cover

API and Vocabulary

Flex

Container element.

  • direction
    • column: boolean
  • align items
    • hAlign: 'start' | 'center' | 'end' | 'stretch',
    • vAlign: ...
    • no boolean flag props with conflicting effects (center, top, ...) - as those will make it impossible to override related effects: <Flex {...} center /> - there is no guarantee that center alignment will be applied
  • arrange space between items
    • space: 'between' | 'around' | 'evenly' | ...
  • gap between items
    • gap: 'gap.small' | 'gap.medium' | 'gap.large'
    • the set of values is intentionally limited at the moment, values should be introduced as long as they will be needed
  • inline: boolean
  • wrap: boolean - allows items to wrap on the next line
  • *padding: 'padding.medium'
    • the set of values is intentionally limited at the moment, values should be introduced as long as they will be needed

Flex.Item

Should be sparingly used, only in cases where styles for individual item should be introduced.

  • item size (along flow direction)
    • size: 'size.small' | 'size.medium' | 'size.half' | 'size.quarter'
    • grow: boolean | ValueOf<FlexGrow>
    • shrink: boolean | ValueOf<FlexShrink>
  • item alignment (CROSS axis)
    • align: 'start | center | end | ... '
  • push
    • push item from the rest of content (along MAIN axis)
    • push: boolean

Q&A

  • Flex or Row (or other name)?
    • at the moment we've agreed to stay with Flex and get on par with CSS Flex capabilities (while intentionally limiting some features, such as reordering of child DOM elements)
  • prop names
    • provided prop names were aimed to largely mimic the ones provided by Flex CSS spec. At times it might seem that there are clear better naming alternatives (that would make markup more readable), however, we have deferred this renaming till the point when component itself won't suggest (by its name) its close correspondence to Flex.
  • semantic names (that aim to match design spec) for some prop values
    • gap and padding of Flex
    • size of Flex.Item
    • the set of values introduced for each of them now is intentionally limited - it will be updated and, ultimately, rebuilt into common design language spec
  • names for semantic prop values ('gap.medium', 'gap.small' - as string keys)
    • it was a conscious decision to provide explicit string keys as prop values - this move, although not being an ideal and most succinct choice for now, will highly alleviate further upcoming variables refactoring, when all the variables will be arranged under common design language schema

@kuzhelov kuzhelov changed the title [WIP] [WIP] feat(layout): Flex proposal Jan 30, 2019
@kuzhelov kuzhelov changed the title [WIP] feat(layout): Flex proposal feat(layout): Flex proposal Feb 5, 2019
@codecov
Copy link

codecov bot commented Feb 6, 2019

Codecov Report

Merging #802 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #802   +/-   ##
=======================================
  Coverage   93.54%   93.54%           
=======================================
  Files          21       21           
  Lines         728      728           
  Branches       69       73    +4     
=======================================
  Hits          681      681           
  Misses         47       47

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update de45998...e99c27a. Read the comment docs.

Copy link
Collaborator

@bmdalex bmdalex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice job, pls take a look at my comments

const renderGap = index !== 0
return (
<>
{renderGap && gap && <Flex.Gap className={gapClasses} />}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the gap logic can be done only once before the loop;

private renderChild: (
  childElement: React.ReactChild,
  renderGap: boolean,
  gapClasses: any // type for classes
) => React.ReactChild = this.props.gap
  ? (childElement, renderGap, gapClasses) => (
      <>
        {renderGap && <Flex.Gap className={gapClasses} />}
        {childElement}
      </>
    )
  : childElement => childElement

and use it as:

return this.renderChild(childElement, index !== 0, gapClasses)

in your React.Children.map function?

Looking at it again it reduces readability a bit so feel free to disregard..

'size.half': '50%',
'size.quarter': '25%',

'size.small': pxToRem(150),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how did we come up with these values?
can we make these part of theme somehow or is that plan for future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is definitely a plan for the future - there are no clear specs on that yet, provided numbers are free to be changed

</Flex.Item>
</Flex>

<Flex gap="gap.small" padding="padding.medium" style={{ minHeight: 200 }}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about having height as prop? I imagine it was considered already? Disregard in that case

Copy link
Contributor Author

@kuzhelov kuzhelov Feb 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, actually, it was - and the main reason for not doing it (for now, at least) is that height wasn't seen as a close attribute of the layout aspects - in other case, this prop is not specific to layout component (the same way then we might argue about adding height to API of Segment).

Also, note that if Flex needs to be provided with some height while being part of some other component, this will be done by styles, not by the props API:

renderComponent = ({ ..., ElementType, styles }) => {
   <ElementType>
       <Flex styles={styles.flex} >
        ....
      </Flex>
  </ElementType>
}

/// myComponentStyles.js
{
  root: ...
  flex: {
    height: '200px'
  }
}

import FlexItem from './FlexItem'

export type FlexGap = 'gap.small' | 'gap.medium' | 'gap.large'
export type FlexPadding = 'padding.medium'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we have just one option here. Moreover why is the value medium? It doesn't make sense without any other values in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree - but lets refine the set of padding values further down the road. What I am not sure at the moment is whether padding should be specified this way, as it is a 2D thing - what if, for instance, we would need to make vertical padding lesser than horizontal one, as it is usually the case for button? medium name was selected just to be consistent with the dictionary we've used so far for size values.

With that being said, I acknowledge the issue, but it was intentionally left visible, as the approach to organise these values (by putting them under general design schema) needs to be introduced as a follow-up work.

@codecov
Copy link

codecov bot commented Feb 7, 2019

Codecov Report

Merging #802 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #802   +/-   ##
=======================================
  Coverage   93.54%   93.54%           
=======================================
  Files          21       21           
  Lines         728      728           
  Branches       69       73    +4     
=======================================
  Hits          681      681           
  Misses         47       47

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update de45998...1a37491. Read the comment docs.

@kuzhelov kuzhelov merged commit d4ca3af into master Feb 8, 2019
@kuzhelov kuzhelov deleted the feat/flex-layout branch February 8, 2019 01:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants