-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Layout components #3277
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
Layout components #3277
Changes from all commits
adca59d
2ad483e
26889de
e89d467
19a1c29
2091157
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { DecoratorFunction } from '@storybook/addons'; | ||
| import React from 'react'; | ||
SaraVieira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| import styled from 'styled-components'; | ||
|
|
||
| const ColoredChildren = styled.div` | ||
| & > div > * { | ||
| --color: rgb(103, 126, 208); | ||
| background: var(--color); | ||
| min-height: 4em; | ||
| min-width: 4em; | ||
| } | ||
| & > div > *:nth-child(6n + 2) { | ||
| --color: rgb(217, 103, 219); | ||
| } | ||
| & > div > *:nth-child(6n + 3) { | ||
| --color: rgb(77, 214, 115); | ||
| } | ||
| & > div > *:nth-child(6n + 4) { | ||
| --color: rgb(248, 110, 91); | ||
| } | ||
| & > div > *:nth-child(6n + 5) { | ||
| --color: rgb(94, 204, 211); | ||
| } | ||
| & > div > *:nth-child(6n + 6) { | ||
| --color: rgb(0, 35, 208); | ||
| } | ||
| & > div > *:nth-child(6n + 7) { | ||
| --color: rgb(224, 174, 72); | ||
| } | ||
| `; | ||
|
|
||
| export const LayoutDecorator: DecoratorFunction = story => ( | ||
| <ColoredChildren>{story()}</ColoredChildren> | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export * from './ThemeDecorator'; | ||
| export * from './LayoutDecorator'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| import React from 'react'; | ||
| import { LayoutDecorator } from '../../../.storybook/decorators'; | ||
|
|
||
| import { Grid, Column, Row } from '.'; | ||
|
|
||
| export default { | ||
| title: 'components/Grid', | ||
| component: Grid, | ||
| decorators: [LayoutDecorator], | ||
| }; | ||
|
|
||
| // replace the text inside with Text variants when available | ||
| export const Span = () => ( | ||
| <Grid> | ||
| <Column span={4}>span 4</Column> | ||
| <Column span={4}>span 4</Column> | ||
| <Column span={4}>span 4</Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const ZeroGap = () => ( | ||
| <Grid columnGap={0}> | ||
| <Column span={4}>span 4</Column> | ||
| <Column span={4}>span 4</Column> | ||
| <Column span={4}>span 4</Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const StartAndEnd = () => ( | ||
| <Grid> | ||
| <Column start={1} end={4}> | ||
| 1 to 4 | ||
| </Column> | ||
| <Column start={6} end={7}> | ||
| 6-7 | ||
| </Column> | ||
| <Column start={9} end={12}> | ||
| 9 to 12 | ||
| </Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const Mixed = () => ( | ||
| <Grid> | ||
| <Column>.</Column> | ||
| <Column span={3}>span 3</Column> | ||
| <Column>.</Column> | ||
| <Column start={7} end={8}> | ||
| 7-8 | ||
| </Column> | ||
| <Column start={11}>11</Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const Overflow = () => ( | ||
| <Grid> | ||
| <Column span={12}>span 12</Column> | ||
| <Column span={6}>span 6</Column> | ||
| <Column span={6}>span 6</Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const ResponsiveSpan = () => ( | ||
| <Grid> | ||
| <Column span={[12, 6]}>span [12, 6]</Column> | ||
| <Column span={[12, 6]}>span [12 , 6]</Column> | ||
| <Column span={12}>span 12</Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const ResponsiveStart = () => ( | ||
| <Grid> | ||
| <Column start={[1, 1, 2]} span={[12, 6, 4]}> | ||
| one | ||
| </Column> | ||
| <Column start={[1, 7, 8]} span={[12, 6, 4]}> | ||
| two | ||
| </Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const Sidebar = () => ( | ||
| <Grid> | ||
| <Column span={[0, 4]}>sidebar</Column> | ||
| <Column span={[12, 8]}>main</Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const WithRow = () => ( | ||
| <Grid> | ||
| <Row>header</Row> | ||
| <Row> | ||
| <Column span={[12, 2]}>sidebar</Column> | ||
| <Column span={[12, 10]}>main</Column> | ||
| </Row> | ||
| <Row> | ||
| <Column start={[0, 5]} span={[12, 4]}> | ||
| footer | ||
| </Column> | ||
| </Row> | ||
| </Grid> | ||
| ); | ||
|
|
||
| export const NestedGrid = () => ( | ||
| <Grid> | ||
| <Row>header</Row> | ||
| <Column span={[12, 12, 2]}>menu</Column> | ||
| <Column span={[12, 12, 10]}> | ||
| <Grid> | ||
| <Column span={[12, 6, 6]}>left</Column> | ||
| <Column span={[12, 6, 6]}>right</Column> | ||
| <Column span={12}>footer</Column> | ||
| </Grid> | ||
| </Column> | ||
| </Grid> | ||
| ); | ||
|
|
||
| /* eslint-disable react/no-array-index-key */ | ||
| export const ImageGallery = () => ( | ||
| <Grid> | ||
| {new Array(12).fill(true).map((value, index) => ( | ||
| <Column | ||
| span={[6, 4, 3]} | ||
| key={index} | ||
| style={{ | ||
| height: 150, | ||
| width: '100%', | ||
| backgroundSize: 'cover', | ||
| backgroundImage: `url(https://i.picsum.photos/id/${index + | ||
| 100}/200/200.jpg)`, | ||
| }} | ||
| /> | ||
| ))} | ||
| </Grid> | ||
| ); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,48 @@ | ||||||||||||||||||||||
| import styled from 'styled-components'; | ||||||||||||||||||||||
| import css from '@styled-system/css'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const fontSize = 1; // rem = 16px | ||||||||||||||||||||||
| const lineHeight = fontSize * 1.5; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export const Grid = styled.div<{ columnGap?: number; rowGap?: number }>( | ||||||||||||||||||||||
| ({ columnGap, rowGap }) => | ||||||||||||||||||||||
| css({ | ||||||||||||||||||||||
| display: 'grid', | ||||||||||||||||||||||
| gridTemplateColumns: 'repeat(12, 1fr)', // always 12 columns | ||||||||||||||||||||||
| gridColumnGap: | ||||||||||||||||||||||
| (typeof columnGap !== 'undefined' ? columnGap : lineHeight * 2) + 'rem', | ||||||||||||||||||||||
| gridRowGap: (typeof rowGap !== 'undefined' ? rowGap : lineHeight) + 'rem', | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // todo: end and span cant be together | ||||||||||||||||||||||
SaraVieira marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| // valid combinations are | ||||||||||||||||||||||
SaraVieira marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| // start | start + end | start + span | span | ||||||||||||||||||||||
SaraVieira marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| // span + end is also possible but not implemented here | ||||||||||||||||||||||
SaraVieira marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| export const Column = styled.div<{ | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what does this improve?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is implementing the Props like you said in your comments 🙂
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. Implementing it this way would give errors on the missing prop in each, right? repro (see end prop): https://codesandbox.io/s/funny-pare-zswfv
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||
| start?: number; | ||||||||||||||||||||||
| end?: number; | ||||||||||||||||||||||
| span?: number; | ||||||||||||||||||||||
| }>(({ start, end, span }) => { | ||||||||||||||||||||||
SaraVieira marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
| const styles: { | ||||||||||||||||||||||
| gridColumnStart?: number | Array<number | string>; | ||||||||||||||||||||||
| gridColumnEnd?: number | string | Array<number> | Array<string>; | ||||||||||||||||||||||
| } = {}; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (Array.isArray(start)) styles.gridColumnStart = start.map(s => s); | ||||||||||||||||||||||
| else if (start) styles.gridColumnStart = start; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (Array.isArray(end)) styles.gridColumnEnd = end.map(s => s + 1); | ||||||||||||||||||||||
| else if (end) styles.gridColumnEnd = end + 1; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (Array.isArray(span)) styles.gridColumnEnd = span.map(s => 'span ' + s); | ||||||||||||||||||||||
| else if (span) styles.gridColumnEnd = 'span ' + span; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return css(styles); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export const Row = styled(Grid).attrs({ span: 12 })( | ||||||||||||||||||||||
| css({ | ||||||||||||||||||||||
| gridColumnEnd: 'span 12', | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import styled from 'styled-components'; | ||
| import css from '@styled-system/css'; | ||
|
|
||
| export const Stack = styled.div<{ | ||
| gap?: number; // theme.space token | ||
| direction?: 'horizontal' | 'vertical'; | ||
| justify?: string; | ||
| align?: string; | ||
| }>(({ gap = 0, direction = 'horizontal', justify, align }) => | ||
| css({ | ||
| display: 'flex', | ||
| flexDirection: direction === 'horizontal' ? 'row' : 'column', | ||
| justifyContent: justify, | ||
| alignItems: align, | ||
|
|
||
| '> *:not(:last-child)': { | ||
| [direction === 'horizontal' ? 'marginRight' : 'marginBottom']: gap, | ||
| }, | ||
| }) | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import React from 'react'; | ||
| import { LayoutDecorator } from '../../../.storybook/decorators'; | ||
|
|
||
| import { Stack } from '.'; | ||
|
|
||
| export default { | ||
| title: 'components/Stack', | ||
| component: Stack, | ||
| decorators: [LayoutDecorator], | ||
| }; | ||
|
|
||
| // replace the text inside with Text variants when available | ||
| export const Defaults = () => ( | ||
| <Stack style={{ height: 100, background: '#343434' }}> | ||
| <div /> | ||
| <div /> | ||
| </Stack> | ||
| ); | ||
|
|
||
| export const WithGap = () => ( | ||
| <Stack gap={4} style={{ height: 100, background: '#343434' }}> | ||
| <div /> | ||
| <div>spacing token as gap</div> | ||
| <div /> | ||
| </Stack> | ||
| ); | ||
|
|
||
| export const Justify = () => ( | ||
| <Stack justify="space-around" style={{ height: 100, background: '#343434' }}> | ||
| <div /> | ||
| <div /> | ||
| </Stack> | ||
| ); | ||
|
|
||
| export const Align = () => ( | ||
| <Stack align="center" style={{ height: 100, background: '#343434' }}> | ||
| <div /> | ||
| <div /> | ||
| </Stack> | ||
| ); |
Uh oh!
There was an error while loading. Please reload this page.