From d5b1a3650b9511ec3796573550968e7ef207909e Mon Sep 17 00:00:00 2001 From: Ling Xing Date: Thu, 20 Aug 2020 12:45:27 -0400 Subject: [PATCH] feat(core-flex-grid): add outsideGutter property --- packages/FlexGrid/FlexGrid.jsx | 71 +-- packages/FlexGrid/FlexGrid.md | 47 ++ packages/FlexGrid/__tests__/FlexGrid.spec.jsx | 7 + .../__snapshots__/FlexGrid.spec.jsx.snap | 468 ++++++++++++++++++ 4 files changed, 563 insertions(+), 30 deletions(-) diff --git a/packages/FlexGrid/FlexGrid.jsx b/packages/FlexGrid/FlexGrid.jsx index 88f986b998..5bdbdcc75d 100644 --- a/packages/FlexGrid/FlexGrid.jsx +++ b/packages/FlexGrid/FlexGrid.jsx @@ -15,35 +15,34 @@ import GutterContext from './gutterContext' const rem = breakpoint => { return `${breakpoints[breakpoint] / 16}rem` } - -const StyledGrid = styled(({ reverseLevel, limitWidth, ...rest }) => )( - ({ reverseLevel, limitWidth }) => ({ - display: 'flex', - flexWrap: 'wrap', - margin: '0 auto', - width: '100%', - 'div&': { padding: 0 }, - ...media.until('sm').css({ - flexDirection: reverseLevel[0] ? 'column-reverse' : 'column', - }), - ...media.from('sm').css({ - ...(limitWidth && { maxWidth: rem('sm') }), - flexDirection: reverseLevel[1] ? 'column-reverse' : 'column', - }), - ...media.from('md').css({ - ...(limitWidth && { maxWidth: rem('md') }), - flexDirection: reverseLevel[2] ? 'column-reverse' : 'column', - }), - ...media.from('lg').css({ - ...(limitWidth && { maxWidth: rem('lg') }), - flexDirection: reverseLevel[3] ? 'column-reverse' : 'column', - }), - ...media.from('xl').css({ - ...(limitWidth && { maxWidth: rem('xl') }), - flexDirection: reverseLevel[4] ? 'column-reverse' : 'column', - }), - }) -) +const StyledGrid = styled(({ reverseLevel, limitWidth, outsideGutter, ...rest }) => ( + +))(({ reverseLevel, limitWidth, outsideGutter }) => ({ + display: 'flex', + flexWrap: 'wrap', + margin: `0 ${!outsideGutter ? '-1rem' : 'auto'}`, + width: !outsideGutter ? undefined : '100%', + 'div&': { padding: 0 }, + ...media.until('sm').css({ + flexDirection: reverseLevel[0] ? 'column-reverse' : 'column', + }), + ...media.from('sm').css({ + ...(limitWidth && { maxWidth: rem('sm') }), + flexDirection: reverseLevel[1] ? 'column-reverse' : 'column', + }), + ...media.from('md').css({ + ...(limitWidth && { maxWidth: rem('md') }), + flexDirection: reverseLevel[2] ? 'column-reverse' : 'column', + }), + ...media.from('lg').css({ + ...(limitWidth && { maxWidth: rem('lg') }), + flexDirection: reverseLevel[3] ? 'column-reverse' : 'column', + }), + ...media.from('xl').css({ + ...(limitWidth && { maxWidth: rem('xl') }), + flexDirection: reverseLevel[4] ? 'column-reverse' : 'column', + }), +})) /** * A mobile-first flexbox grid. @@ -54,6 +53,7 @@ const StyledGrid = styled(({ reverseLevel, limitWidth, ...rest }) => - + {children} @@ -81,6 +87,10 @@ FlexGrid.propTypes = { * Whether or not to include gutters in between columns. */ gutter: PropTypes.bool, + /** + * Whether or not to include gutter at the ends to the left and right of the FlexGrid + */ + outsideGutter: PropTypes.bool, /** * Choose if the item order should be reversed from the 'xs' breakpoint. When you pass in false, the order will be normal from the xs breakpoint. By default, it inherits the behaviour set by the preceding prop. */ @@ -110,6 +120,7 @@ FlexGrid.propTypes = { FlexGrid.defaultProps = { limitWidth: true, gutter: true, + outsideGutter: true, xsReverse: undefined, smReverse: undefined, mdReverse: undefined, diff --git a/packages/FlexGrid/FlexGrid.md b/packages/FlexGrid/FlexGrid.md index 17712523d1..83a6dcf6e2 100644 --- a/packages/FlexGrid/FlexGrid.md +++ b/packages/FlexGrid/FlexGrid.md @@ -74,6 +74,53 @@ horizontal padding from all child columns. ``` +### Removing the outside gutter + +In some layouts, there might be the need to remove the gutter from the left and right of the row. +For example, if the layout requires a `FlexGrid` to be nested under another `FlexGrid` Column, +the child `FlexGrid`'s columns will not line up with the parent `FlexGrid`'s columns due to the additional gutter between the child columns. + +It is possible to avoid this situation while keeping the gutters between the columns, +to do so, pass `outsideGutter={false}` to the child `FlexGrid`. +This will remove the gutter on the left and the right of the `FlexGrid`. + +`outsideGutter` should not be false if parent `FlexGrid` has `gutter={false}`. + +```jsx { "props": { "className": "docs_full-width-playground docs_flex-grid-coloring" } } + + + + + Parent Column + + + + + Parent Column + + + + + + + + + + Child Column + + + + + Child Column + + + + + + + +``` + ### Working with full-width and limited-width content Pages should have multiple instances of `FlexGrid` to separate full-width content and regular limited-width content. diff --git a/packages/FlexGrid/__tests__/FlexGrid.spec.jsx b/packages/FlexGrid/__tests__/FlexGrid.spec.jsx index 94d4cdb864..7b3eb7e6f5 100644 --- a/packages/FlexGrid/__tests__/FlexGrid.spec.jsx +++ b/packages/FlexGrid/__tests__/FlexGrid.spec.jsx @@ -107,4 +107,11 @@ describe('FlexGrid', () => { expect(flexGrid).toMatchSnapshot() }) + + it('renders with no outside gutter', () => { + const { flexGrid } = doMount({ + outsideGutter: true, + }) + expect(flexGrid).toMatchSnapshot() + }) }) diff --git a/packages/FlexGrid/__tests__/__snapshots__/FlexGrid.spec.jsx.snap b/packages/FlexGrid/__tests__/__snapshots__/FlexGrid.spec.jsx.snap index 59a2c4ae8f..d482839477 100644 --- a/packages/FlexGrid/__tests__/__snapshots__/FlexGrid.spec.jsx.snap +++ b/packages/FlexGrid/__tests__/__snapshots__/FlexGrid.spec.jsx.snap @@ -1108,6 +1108,474 @@ div.c0 { `; +exports[`FlexGrid renders with no outside gutter 1`] = ` +div.c2 { + padding-left: 1rem; + padding-right: 1rem; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} + +.c1 { + width: 100%; +} + +div.c1 { + margin: 0 auto; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; +} + +.c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: 0 auto; + width: 100%; +} + +div.c0 { + padding: 0; +} + +@media (max-width:575px) { + .c2 { + display: block; + text-align: inherit; + } +} + +@media (min-width:576px) { + .c2 { + display: block; + text-align: inherit; + } +} + +@media (min-width:768px) { + .c2 { + display: block; + text-align: inherit; + } +} + +@media (min-width:992px) { + .c2 { + display: block; + text-align: inherit; + } +} + +@media (min-width:1200px) { + .c2 { + display: block; + text-align: inherit; + } +} + +@media (max-width:575px) { + div.c1 { + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } +} + +@media (min-width:576px) { + div.c1 { + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } +} + +@media (min-width:768px) { + div.c1 { + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } +} + +@media (min-width:992px) { + div.c1 { + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } +} + +@media (min-width:1200px) { + div.c1 { + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } +} + +@media (max-width:575px) { + .c0 { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } +} + +@media (min-width:576px) { + .c0 { + max-width: 36rem; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } +} + +@media (min-width:768px) { + .c0 { + max-width: 48rem; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } +} + +@media (min-width:992px) { + .c0 { + max-width: 62rem; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } +} + +@media (min-width:1200px) { + .c0 { + max-width: 75rem; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } +} + + +
+ + + + + +
+ + + + + +
+ 1st column content +
+ +
+
+
+ + + + + + +
+ 2nd column content +
+ +
+
+
+ +
+
+
+
+
+
+
+
+`; + exports[`FlexGrid supports responsive reversal 1`] = ` div.c2 { padding-left: 1rem;