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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3da9172
initial
kuzhelov-ms Jan 30, 2019
9c93a0f
remove support for 'center' prop
kuzhelov-ms Jan 30, 2019
711e5bb
refactor the API
kuzhelov-ms Jan 31, 2019
8145e7e
Merge branch 'master' into feat/flex-layout
kuzhelov Jan 31, 2019
ab39fc4
rename refactoring
kuzhelov-ms Feb 6, 2019
2970fa3
Merge branch 'master' into feat/flex-layout
kuzhelov-ms Feb 6, 2019
9a3d819
merge master
kuzhelov-ms Feb 6, 2019
6f4b06a
remove unnecessary type cast
kuzhelov-ms Feb 6, 2019
816f56b
remove prototyping shortcuts
kuzhelov-ms Feb 6, 2019
c36771a
adjust marker strategy for Flex Item
kuzhelov-ms Feb 6, 2019
ddc2eb7
revert marker strategy for flex item
kuzhelov-ms Feb 6, 2019
f0eb6a3
introduce semantic names to size values
kuzhelov-ms Feb 6, 2019
41d7750
apply semantic size values to flex item styles
kuzhelov-ms Feb 6, 2019
86d9625
fix prop types of Flex component
kuzhelov-ms Feb 6, 2019
9dbd7ea
remove unnecessary 'as' prop in media card example
kuzhelov-ms Feb 6, 2019
cad2801
rename type of flex item variables
kuzhelov-ms Feb 6, 2019
26309e3
Merge branch 'master' into feat/flex-layout
kuzhelov Feb 6, 2019
e1ba117
fix typo
kuzhelov-ms Feb 6, 2019
d7fbcf6
Merge branch 'feat/flex-layout' of https://github.com/stardust-ui/rea…
kuzhelov-ms Feb 6, 2019
b0d6311
remove unnecessary comments
kuzhelov-ms Feb 6, 2019
0520069
update flex item marker comment
kuzhelov-ms Feb 6, 2019
101f03c
further remove stale comments
kuzhelov-ms Feb 6, 2019
3819197
further refactoring
kuzhelov-ms Feb 6, 2019
8115ad2
rename refactoring
kuzhelov-ms Feb 6, 2019
9248534
Merge branch 'master' into feat/flex-layout
kuzhelov Feb 6, 2019
4bb83c1
add padding to examples
kuzhelov-ms Feb 6, 2019
52c4e33
address review comments
kuzhelov-ms Feb 6, 2019
911eca2
Merge branch 'feat/flex-layout' of https://github.com/stardust-ui/rea…
kuzhelov-ms Feb 6, 2019
2d6e7a2
add types
kuzhelov-ms Feb 6, 2019
10ab8b7
simplify gap render condition
kuzhelov-ms Feb 6, 2019
447f745
remove obsolete comment
kuzhelov-ms Feb 6, 2019
bcd9929
optimize the amount of types necessary
kuzhelov-ms Feb 7, 2019
e0a4ea3
remove inline style prop
kuzhelov-ms Feb 7, 2019
31f1bd4
imtroduce type for Flex Gap
kuzhelov-ms Feb 7, 2019
5d0682e
introduce additional flex item size option
kuzhelov-ms Feb 7, 2019
81a975b
refine prop types of flex item
kuzhelov-ms Feb 7, 2019
62c2000
use built-in TS types
kuzhelov-ms Feb 7, 2019
fc1582e
minor syntax simplification
kuzhelov-ms Feb 7, 2019
e26502f
add type for flex variables in styles func
kuzhelov-ms Feb 7, 2019
7797fc1
expose prop types to public interface
kuzhelov-ms Feb 7, 2019
b3f2e86
reorder preferences of merged styles
kuzhelov-ms Feb 7, 2019
c87230f
upd
kuzhelov-ms Feb 7, 2019
daa1601
Merge branch 'master' into feat/flex-layout
kuzhelov Feb 7, 2019
8dab420
update changelog
kuzhelov-ms Feb 7, 2019
5f1658b
Merge branch 'feat/flex-layout' of https://github.com/stardust-ui/rea…
kuzhelov-ms Feb 7, 2019
e99c27a
upd changelog
kuzhelov-ms Feb 7, 2019
1a37491
upd media card example
kuzhelov-ms Feb 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add single search flavor for `Dropdown` component @Bugaa92 ([#839](https://github.com/stardust-ui/react/pull/839))
- Add multiple selection flavor for `Dropdown` component @Bugaa92 ([#845](https://github.com/stardust-ui/react/pull/845))
- Add `black` and `white` options for the `color` prop of the `Label` component @mnajdova ([#855](https://github.com/stardust-ui/react/pull/855))
- Add `Flex` component @kuzhelov ([#802](https://github.com/stardust-ui/react/pull/802))

<!--------------------------------[ v0.20.0 ]------------------------------- -->
## [v0.20.0](https://github.com/stardust-ui/react/tree/v0.20.0) (2019-02-06)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react'
import { Flex, Segment } from '@stardust-ui/react'

const FlexExampleColumns = () => (
<>
<Flex gap="gap.small" padding="padding.medium">
<Flex.Item size="size.half">
<Segment content="1/2" />
</Flex.Item>

<Flex.Item size="size.half">
<Segment content="1/2" />
</Flex.Item>
</Flex>

<Flex gap="gap.small" padding="padding.medium">
<Flex.Item size="size.quarter">
<Segment content="1/4" />
</Flex.Item>

<Flex.Item size="size.half">
<Segment content="1/2" />
</Flex.Item>

<Flex.Item size="size.quarter">
<Segment content="1/4" />
</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'
  }
}

<Flex.Item size="size.half">
<Segment content="Full-height, even when my content doesn't fill the space." />
</Flex.Item>

<Flex.Item size="size.half">
<Segment content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mollis velit non gravida venenatis. Praesent consequat lectus purus, ut scelerisque velit condimentum eu. Maecenas sagittis ante ut turpis varius interdum. Quisque tellus ipsum, eleifend non ipsum id, suscipit ultricies neque." />
</Flex.Item>
</Flex>
</>
)

export default FlexExampleColumns
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react'
import { Flex, Input, Button, Label } from '@stardust-ui/react'

const FlexExampleInput = () => (
<Flex gap="gap.medium" debug>
<Flex.Item grow>
<Flex>
<Label
icon="plane"
styles={{ background: 'darkgrey', height: 'auto', padding: '0 15px' }}
/>

<Flex.Item grow>
<Input placeholder="Enter your flight #" fluid />
</Flex.Item>
</Flex>
</Flex.Item>

<Button content="Load" />
</Flex>
)

export default FlexExampleInput
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as React from 'react'
import { Flex, Segment } from '@stardust-ui/react'

const FlexExampleItemsAlignment = () => (
<Flex column gap="gap.large" hAlign="center" vAlign="center" debug>
{[
[
{ hAlign: 'start', vAlign: 'start' },
{ hAlign: 'start', vAlign: 'center' },
{ hAlign: 'start', vAlign: 'end' },
],
[
{ hAlign: 'center', vAlign: 'start' },
{ hAlign: 'center', vAlign: 'center' },
{ hAlign: 'center', vAlign: 'end' },
],
[
{ hAlign: 'end', vAlign: 'start' },
{ hAlign: 'end', vAlign: 'center' },
{ hAlign: 'end', vAlign: 'end' },
],
].map(rowOfAlignmentProps => (
<Flex gap="gap.large">
{rowOfAlignmentProps.map((alignmentProps: any) => (
<Flex inline {...alignmentProps} style={{ width: '100px', height: '100px' }} debug>
<Segment styles={{ width: '30px', height: '30px' }} />
</Flex>
))}
</Flex>
))}
</Flex>
)

export default FlexExampleItemsAlignment
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react'
import { Flex, Image, Text, Header } from '@stardust-ui/react'

const FlexExampleMediaCard = () => (
<Flex gap="gap.medium" padding="padding.medium" debug>
<Flex.Item size="size.medium">
<div style={{ position: 'relative' }}>
<Image fluid src="public/images/avatar/large/ade.jpg" />
</div>
</Flex.Item>

<Flex.Item grow>
<Flex column gap="gap.small" vAlign="stretch">
<Flex space="between">
<Header as="h3" content="LOREM IPSUM" />
<Text as="pre" content="Oct 24th, 00:01" />
</Flex>

<Text content="Man braid iPhone locavore hashtag pop-up, roof party forage heirloom chillwave brooklyn yr 8-bit gochujang blog." />

<Flex.Item push>
<Text as="pre" content="COPYRIGHT: Stardust-UI Inc." />
</Flex.Item>
</Flex>
</Flex.Item>
</Flex>
)

export default FlexExampleMediaCard
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react'
import { Flex, Segment } from '@stardust-ui/react'

const FlexExampleMixedAlignment = () => (
<Flex gap="gap.small" hAlign="center" vAlign="center" debug>
<Flex.Item align="start" size="size.small">
<Segment content="This cell should be top aligned." />
</Flex.Item>

<Flex.Item align="stretch" size="size.small">
<Segment content="Curabitur pulvinar dolor lectus, quis porta turpis ullamcorper nec. Quisque eget varius turpis, quis iaculis nibh. Ut interdum ligula id metus hendrerit cursus. Integer eu leo felis. Aenean commodo ultrices nunc, sit amet blandit elit gravida in. Sed est ligula, ornare ac nisi adipiscing, iaculis facilisis tellus." />
</Flex.Item>

<Flex.Item align="center" size="size.small">
<Segment content="This cell should be center-aligned." />
</Flex.Item>

<Flex.Item align="end" size="size.small">
<Segment content="This cell should be bottom-aligned." />
</Flex.Item>
</Flex>
)

export default FlexExampleMixedAlignment
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react'
import { Flex, Button } from '@stardust-ui/react'

const FlexExampleNavMenu = () => (
<Flex gap="gap.small" debug>
<Button content="Logo" icon="chess rook" />

<Flex.Item push>
<Button content="Page 1" />
</Flex.Item>

<Button content="Page 2" />
<Button content="Page 3" />
</Flex>
)

export default FlexExampleNavMenu
40 changes: 40 additions & 0 deletions docs/src/examples/components/Flex/Types/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react'
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Types = () => (
<ExampleSection title="Types">
<ComponentExample
title="Media Card"
description="Flex items alignment options."
examplePath="components/Flex/Types/FlexExampleMediaCard"
/>
<ComponentExample
title="Input"
description="Flex items alignment options."
examplePath="components/Flex/Types/FlexExampleInput"
/>
<ComponentExample
title="Nav Menu"
description="Flex items alignment options."
examplePath="components/Flex/Types/FlexExampleNavMenu"
/>
<ComponentExample
title="Items Alignment"
description="Flex items alignment options."
examplePath="components/Flex/Types/FlexExampleItemsAlignment"
/>
<ComponentExample
title="Mixed Alignment"
description="Flex mixed alignment feature."
examplePath="components/Flex/Types/FlexExampleMixedAlignment"
/>
<ComponentExample
title="Columns (item size)"
description="Flex columns example."
examplePath="components/Flex/Types/FlexExampleColumns"
/>
</ExampleSection>
)

export default Types
10 changes: 10 additions & 0 deletions docs/src/examples/components/Flex/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as React from 'react'
import Types from './Types'

const FlexExamples = () => (
<>
<Types />
</>
)

export default FlexExamples
112 changes: 112 additions & 0 deletions packages/react/src/components/Flex/Flex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import * as PropTypes from 'prop-types'
import * as React from 'react'
import * as _ from 'lodash'
import cx from 'classnames'

import { UIComponent, commonPropTypes } from '../../lib'
import { ReactProps } from '../../types'
import FlexItem from './FlexItem'
import FlexGap from './FlexGap'

export interface FlexProps {
/** Defines if container should be inline element. */
inline?: boolean

/** Sets vertical flow direction. */
column?: boolean

/** Allows overflow items to wrap on the next container's line. */
wrap?: boolean

/** Controls items alignment in horizontal direction. */
hAlign?: 'start' | 'center' | 'end' | 'stretch'

/** Controls items alignment in vertical direction. */
vAlign?: 'start' | 'center' | 'end' | 'stretch'

/** Defines strategy for distributing remaining space between items. */
space?: 'around' | 'between' | 'evenly'

/** Defines gap between each two adjacent child items. */
gap?: 'gap.small' | 'gap.medium' | 'gap.large'

/** Defines container's padding. */
padding?: 'padding.medium'

/** Enables debug mode. */
debug?: boolean

/** Orders container to fill all parent's space available. */
fill?: boolean
}

/**
* Arrange group of items aligned towards common direction.
*/
class Flex extends UIComponent<ReactProps<FlexProps>> {
static Item = FlexItem

static Gap = FlexGap

static displayName = 'Flex'
static className = 'ui-flex'

static defaultProps = {
as: 'div',
}

public static propTypes = {
...commonPropTypes.createCommon({
content: false,
}),

inline: PropTypes.bool,

column: PropTypes.bool,

wrap: PropTypes.bool,

hAlign: PropTypes.oneOf(['start', 'center', 'end', 'stretch']),
vAlign: PropTypes.oneOf(['start', 'center', 'end', 'stretch']),

space: PropTypes.oneOf(['around', 'between', 'evenly']),

gap: PropTypes.oneOf(['gap.small', 'gap.medium', 'gap.large']),

padding: PropTypes.oneOf(['padding.medium']),
fill: PropTypes.bool,

debug: PropTypes.bool,
}

renderComponent({ ElementType, classes, unhandledProps }): React.ReactNode {
return (
<ElementType className={classes.root} {...unhandledProps}>
{this.renderChildren(classes.gap)}
</ElementType>
)
}

renderChildren = (gapClasses: string) => {
const { column, gap, children } = this.props

return React.Children.map(children, (child: React.ReactElement<any>, index) => {
const childElement =
child.type && ((child.type as any) as typeof FlexItem).__isFlexItem
? React.cloneElement(child, {
flexDirection: column ? 'column' : 'row',
})
: child

const renderGap = index !== 0
return (
<>
{renderGap && gap && <Flex.Gap className={cx(`${Flex.className}__gap`, gapClasses)} />}
{childElement}
</>
)
})
}
}

export default Flex
6 changes: 6 additions & 0 deletions packages/react/src/components/Flex/FlexGap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from 'react'

const FlexGap: React.FC<any> = ({ className }) => <div className={className} />
FlexGap.displayName = 'FlexGap'

export default FlexGap
Loading