[UI Framework] Port KuiFlexItem, KuiFlexGroup, and KuiFlexGrid components from K7. (#14387)

* Port KuiFlexItem, KuiFlexGroup, and KuiFlexGrid components from K7.
* Remove unused breakpoints.
This commit is contained in:
CJ Cenizal 2017-10-10 11:23:59 -07:00 committed by GitHub
parent e635d25b26
commit 1563213459
33 changed files with 1123 additions and 1 deletions

View file

@ -990,6 +990,295 @@ main {
padding: 20px;
white-space: nowrap; }
.kuiFlexGroup {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGroup .kuiFlexItem {
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
-ms-flex-positive: 1;
flex-grow: 1;
-webkit-flex-basis: 0;
-ms-flex-preferred-size: 0;
flex-basis: 0; }
.kuiFlexGroup.kuiFlexGroup--gutterSmall > .kuiFlexItem + .kuiFlexItem {
margin-left: 8px; }
.kuiFlexGroup.kuiFlexGroup--gutterMedium > .kuiFlexItem + .kuiFlexItem {
margin-left: 16px; }
.kuiFlexGroup.kuiFlexGroup--gutterLarge > .kuiFlexItem + .kuiFlexItem {
margin-left: 24px; }
.kuiFlexGroup.kuiFlexGroup--gutterExtraLarge > .kuiFlexItem + .kuiFlexItem {
margin-left: 40px; }
.kuiFlexGroup.kuiFlexGroup--justifyContentSpaceBetween {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between; }
.kuiFlexGroup.kuiFlexGroup--justifyContentSpaceAround {
-webkit-justify-content: space-around;
-ms-flex-pack: distribute;
justify-content: space-around; }
.kuiFlexGroup.kuiFlexGroup--justifyContentCenter {
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center; }
.kuiFlexGroup.kuiFlexGroup--justifyContentFlexEnd {
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end; }
.kuiFlexGroup.kuiFlexGroup--alignItemsStart {
-webkit-box-align: start;
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start; }
.kuiFlexGroup.kuiFlexGroup--alignItemsCenter {
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center; }
.kuiFlexGroup.kuiFlexGroup--alignItemsEnd {
-webkit-box-align: end;
-webkit-align-items: flex-end;
-ms-flex-align: end;
align-items: flex-end; }
@media only screen and (max-width: 768px) {
.kuiFlexGroup {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap; } }
.kuiFlexGrid {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-bottom: 0; }
.kuiFlexGrid > .kuiFlexItem {
-webkit-box-flex: 0;
-webkit-flex-grow: 0;
-ms-flex-positive: 0;
flex-grow: 0; }
.kuiFlexGrid > .kuiFlexItem.kuiFlexItem--flexGrowZero {
-webkit-box-flex: 0 !important;
-webkit-flex-grow: 0 !important;
-ms-flex-positive: 0 !important;
flex-grow: 0 !important;
-webkit-flex-basis: auto !important;
-ms-flex-preferred-size: auto !important;
flex-basis: auto !important; }
/**
* Uncouple the gutter margin from the column widths to support cases where we use a FlexGrid
* without columns.
*/
.kuiFlexGrid--gutterSmall > .kuiFlexItem {
margin: 4px; }
.kuiFlexGrid--gutterSmall {
margin: -4px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterSmall.kuiFlexGrid--fourths > .kuiFlexItem {
-webkit-flex-basis: calc(25% - 8px);
-ms-flex-preferred-size: calc(25% - 8px);
flex-basis: calc(25% - 8px); }
.kuiFlexGrid--gutterSmall {
margin: -4px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterSmall.kuiFlexGrid--thirds > .kuiFlexItem {
-webkit-flex-basis: calc(33.3% - 8px);
-ms-flex-preferred-size: calc(33.3% - 8px);
flex-basis: calc(33.3% - 8px); }
.kuiFlexGrid--gutterSmall {
margin: -4px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterSmall.kuiFlexGrid--halves > .kuiFlexItem {
-webkit-flex-basis: calc(50% - 8px);
-ms-flex-preferred-size: calc(50% - 8px);
flex-basis: calc(50% - 8px); }
/**
* Uncouple the gutter margin from the column widths to support cases where we use a FlexGrid
* without columns.
*/
.kuiFlexGrid--gutterMedium > .kuiFlexItem {
margin: 8px; }
.kuiFlexGrid--gutterMedium {
margin: -8px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterMedium.kuiFlexGrid--fourths > .kuiFlexItem {
-webkit-flex-basis: calc(25% - 16px);
-ms-flex-preferred-size: calc(25% - 16px);
flex-basis: calc(25% - 16px); }
.kuiFlexGrid--gutterMedium {
margin: -8px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterMedium.kuiFlexGrid--thirds > .kuiFlexItem {
-webkit-flex-basis: calc(33.3% - 16px);
-ms-flex-preferred-size: calc(33.3% - 16px);
flex-basis: calc(33.3% - 16px); }
.kuiFlexGrid--gutterMedium {
margin: -8px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterMedium.kuiFlexGrid--halves > .kuiFlexItem {
-webkit-flex-basis: calc(50% - 16px);
-ms-flex-preferred-size: calc(50% - 16px);
flex-basis: calc(50% - 16px); }
/**
* Uncouple the gutter margin from the column widths to support cases where we use a FlexGrid
* without columns.
*/
.kuiFlexGrid--gutterLarge > .kuiFlexItem {
margin: 12px; }
.kuiFlexGrid--gutterLarge {
margin: -12px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterLarge.kuiFlexGrid--fourths > .kuiFlexItem {
-webkit-flex-basis: calc(25% - 24px);
-ms-flex-preferred-size: calc(25% - 24px);
flex-basis: calc(25% - 24px); }
.kuiFlexGrid--gutterLarge {
margin: -12px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterLarge.kuiFlexGrid--thirds > .kuiFlexItem {
-webkit-flex-basis: calc(33.3% - 24px);
-ms-flex-preferred-size: calc(33.3% - 24px);
flex-basis: calc(33.3% - 24px); }
.kuiFlexGrid--gutterLarge {
margin: -12px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterLarge.kuiFlexGrid--halves > .kuiFlexItem {
-webkit-flex-basis: calc(50% - 24px);
-ms-flex-preferred-size: calc(50% - 24px);
flex-basis: calc(50% - 24px); }
/**
* Uncouple the gutter margin from the column widths to support cases where we use a FlexGrid
* without columns.
*/
.kuiFlexGrid--gutterXLarge > .kuiFlexItem {
margin: 16px; }
.kuiFlexGrid--gutterXLarge {
margin: -16px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterXLarge.kuiFlexGrid--fourths > .kuiFlexItem {
-webkit-flex-basis: calc(25% - 32px);
-ms-flex-preferred-size: calc(25% - 32px);
flex-basis: calc(25% - 32px); }
.kuiFlexGrid--gutterXLarge {
margin: -16px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterXLarge.kuiFlexGrid--thirds > .kuiFlexItem {
-webkit-flex-basis: calc(33.3% - 32px);
-ms-flex-preferred-size: calc(33.3% - 32px);
flex-basis: calc(33.3% - 32px); }
.kuiFlexGrid--gutterXLarge {
margin: -16px;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch; }
.kuiFlexGrid--gutterXLarge.kuiFlexGrid--halves > .kuiFlexItem {
-webkit-flex-basis: calc(50% - 32px);
-ms-flex-preferred-size: calc(50% - 32px);
flex-basis: calc(50% - 32px); }
/**
* 1. Allow KuiPanels to expand to fill the item.
*/
.kuiFlexItem {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/* 1 */
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
/* 1 */
/*
* 1. We need the extra specificity here to override the FlexGroup > FlexItem styles.
* 2. FlexItem can be manually set to not grow if needed.
*/ }
.kuiFlexItem.kuiFlexItem--flexGrowZero {
/* 1 */
-webkit-box-flex: 0;
-webkit-flex-grow: 0;
-ms-flex-positive: 0;
flex-grow: 0;
/* 2 */
-webkit-flex-basis: auto;
-ms-flex-preferred-size: auto;
flex-basis: auto;
/* 2 */ }
@media only screen and (max-width: 768px) {
.kuiFlexItem {
width: 100% !important;
-webkit-flex-basis: 100% !important;
-ms-flex-preferred-size: 100% !important;
flex-basis: 100% !important;
margin-left: 0 !important;
margin-bottom: 16px !important; } }
/**
* 1. Set inline-block so this wrapper shrinks to fit the input.
*/

View file

@ -12,3 +12,17 @@
background-color: #272727;
padding: 10px;
}
.guideDemo__highlightGrid {
.kuiFlexItem {
background: transparentize(#0096CC, .9);
padding: 16px;
}
}
.guideDemo__highlightGridWrap {
.kuiFlexItem div {
background: transparentize(#0096CC, .9);
padding: 16px;
}
}

View file

@ -34,7 +34,7 @@ export class GuideDemo extends Component {
}
render() {
const classes = classNames('guideDemo', {
const classes = classNames('guideDemo', this.props.className, {
'guideDemo--fullScreen': this.props.isFullScreen,
'guideDemo--darkTheme': this.props.isDarkTheme,
'theme-dark': this.props.isDarkTheme,

View file

@ -39,6 +39,9 @@ import EventsSandbox
import ExpressionExample
from '../../views/expression/expression_example';
import FlexExample
from '../../views/flex/flex_example';
import FormExample
from '../../views/form/form_example';
@ -171,6 +174,9 @@ const components = [{
name: 'Expression',
component: ExpressionExample,
hasReact: true,
}, {
name: 'Flex',
component: FlexExample,
}, {
name: 'Form',
component: FormExample,

View file

@ -0,0 +1,199 @@
import React from 'react';
import { renderToHtml } from '../../services';
import {
GuideCode,
GuideDemo,
GuidePage,
GuideSection,
GuideSectionTypes,
GuideText,
} from '../../components';
import FlexGroup from './flex_group';
const flexGroupSource = require('!!raw!./flex_group');
const flexGroupHtml = renderToHtml(FlexGroup);
import FlexItems from './flex_items';
const flexItemsSource = require('!!raw!./flex_items');
const flexItemsHtml = renderToHtml(FlexItems);
import FlexGutter from './flex_gutter';
const flexGutterSource = require('!!raw!./flex_gutter');
const flexGutterHtml = renderToHtml(FlexGutter);
import FlexGrow from './flex_grow';
const flexGrowSource = require('!!raw!./flex_grow');
const flexGrowHtml = renderToHtml(FlexGrow);
import FlexJustify from './flex_justify';
const flexJustifySource = require('!!raw!./flex_justify');
const flexJustifyHtml = renderToHtml(FlexJustify);
import FlexGrid from './flex_grid';
const flexGridSource = require('!!raw!./flex_grid');
const flexGridHtml = renderToHtml(FlexGrid);
import FlexGridColumns from './flex_grid_columns';
const flexGridColumnsSource = require('!!raw!./flex_grid_columns');
const flexGridColumnsHtml = renderToHtml(FlexGridColumns);
import FlexNest from './flex_nest';
const flexNestSource = require('!!raw!./flex_nest');
const flexNestHtml = renderToHtml(FlexNest);
export default props => (
<GuidePage title={props.route.name}>
<GuideSection
title="FlexGroup is for a single row layout"
source={[{
type: GuideSectionTypes.JS,
code: flexGroupSource,
}, {
type: GuideSectionTypes.HTML,
code: flexGroupHtml,
}]}
>
<GuideText>
<GuideCode>FlexGroup</GuideCode> is useful for setting up layouts for a <strong>single row</strong> of
content. By default any <GuideCode>FlexItem</GuideCode> within <GuideCode>FlexGroup</GuideCode> will
stretch and grow to match their siblings.
</GuideText>
<GuideDemo className="guideDemo__highlightGrid"><FlexGroup /></GuideDemo>
</GuideSection>
<GuideSection
title="FlexGroup accepts infinite items"
source={[{
type: GuideSectionTypes.JS,
code: flexItemsSource,
}, {
type: GuideSectionTypes.HTML,
code: flexItemsHtml,
}]}
>
<GuideText>
Same code as above. Notice that <GuideCode>FlexItem</GuideCode> creates equal width items
no matter the number of siblings. <GuideCode>FlexGroup</GuideCode> never wraps.
</GuideText>
<GuideDemo className="guideDemo__highlightGrid"><FlexItems /></GuideDemo>
</GuideSection>
<GuideSection
title="FlexItem can individually turn off stretching"
source={[{
type: GuideSectionTypes.JS,
code: flexGrowSource,
}, {
type: GuideSectionTypes.HTML,
code: flexGrowHtml,
}]}
>
<GuideText>
Sometimes you do not want a <GuideCode>FlexItem</GuideCode> to grow. It
can be turned off on each item individually.
</GuideText>
<GuideDemo className="guideDemo__highlightGrid"><FlexGrow /></GuideDemo>
</GuideSection>
<GuideSection
title="FlexGroup can justify and align"
source={[{
type: GuideSectionTypes.JS,
code: flexJustifySource,
}, {
type: GuideSectionTypes.HTML,
code: flexJustifyHtml,
}]}
>
<GuideText>
<GuideCode>FlexGroup</GuideCode>s can also
use <GuideCode>justifyContent</GuideCode> and <GuideCode>alignItems</GuideCode>props
that accept normal flex-box paramenters. Below are some common scenarios,
where you need to separate two items, center justify a single one, or
center an item vertically. Note the usage
of <GuideCode>FlexItem</GuideCode>s with <GuideCode>grow=false</GuideCode> so that they do not stretch.
</GuideText>
<GuideDemo className="guideDemo__highlightGrid"><FlexJustify /></GuideDemo>
</GuideSection>
<GuideSection
title="FlexGrids are for repeatable grids"
source={[{
type: GuideSectionTypes.JS,
code: flexGridSource,
}, {
type: GuideSectionTypes.HTML,
code: flexGridHtml,
}]}
>
<GuideText>
<GuideCode>FlexGrid</GuideCode> is a more rigid component that sets multiple, wrapping
rows of same width items.
</GuideText>
<GuideDemo className="guideDemo__highlightGridWrap"><FlexGrid /></GuideDemo>
</GuideSection>
<GuideSection
title="FlexGrids can have set column widths"
source={[{
type: GuideSectionTypes.JS,
code: flexGridColumnsSource,
}, {
type: GuideSectionTypes.HTML,
code: flexGridColumnsHtml,
}]}
>
<GuideText>
You can set a <GuideCode>columns</GuideCode> prop to specify
anywhere between 2-4 columns. Any more would likely break on laptop screens.
</GuideText>
<GuideDemo className="guideDemo__highlightGridWrap"><FlexGridColumns /></GuideDemo>
</GuideSection>
<GuideSection
title="FlexGrids and FlexGroups can nest"
source={[{
type: GuideSectionTypes.JS,
code: flexNestSource,
}, {
type: GuideSectionTypes.HTML,
code: flexNestHtml,
}]}
>
<GuideText>
<GuideCode>FlexGroup</GuideCode> and <GuideCode>FlexGrid</GuideCode> can nest
within themselves indefinitely. For example, here we turn off the growth on a
<GuideCode>FlexGroup</GuideCode>, then nest a grid inside of it.
</GuideText>
<GuideDemo className="guideDemo__highlightGrid"><FlexNest /></GuideDemo>
</GuideSection>
<GuideSection
title="Gutter sizing can be used on either FlexGroups or FlexGrids"
source={[{
type: GuideSectionTypes.JS,
code: flexGutterSource,
}, {
type: GuideSectionTypes.HTML,
code: flexGutterHtml,
}]}
>
<GuideText>
The <GuideCode>gutterSize</GuideCode> prop can be applied to either a
<GuideCode>FlexGroup</GuideCode> or a <GuideCode>FlexGrid</GuideCode> to adjust the
spacing between <GuideCode>FlexItem</GuideCode>s.
</GuideText>
<GuideDemo className="guideDemo__highlightGrid"><FlexGutter /></GuideDemo>
</GuideSection>
</GuidePage>
);

View file

@ -0,0 +1,22 @@
import React from 'react';
import {
KuiFlexGrid,
KuiFlexItem,
} from '../../../../components';
const ITEM_STYLE = { width: '300px' };
export default () => (
<div>
<KuiFlexGrid>
<KuiFlexItem style={ITEM_STYLE}><div>One</div></KuiFlexItem>
<KuiFlexItem style={ITEM_STYLE}><div>Two</div></KuiFlexItem>
<KuiFlexItem style={ITEM_STYLE}><div>Three</div></KuiFlexItem>
<KuiFlexItem style={ITEM_STYLE}><div>Four</div></KuiFlexItem>
<KuiFlexItem style={ITEM_STYLE}><div>Five</div></KuiFlexItem>
<KuiFlexItem style={ITEM_STYLE}><div>Six</div></KuiFlexItem>
<KuiFlexItem style={ITEM_STYLE}><div>Seven</div></KuiFlexItem>
</KuiFlexGrid>
</div>
);

View file

@ -0,0 +1,20 @@
import React from 'react';
import {
KuiFlexGrid,
KuiFlexItem,
} from '../../../../components';
export default () => (
<div>
<KuiFlexGrid columns={3}>
<KuiFlexItem><div>One</div></KuiFlexItem>
<KuiFlexItem><div>Two</div></KuiFlexItem>
<KuiFlexItem><div>Three</div></KuiFlexItem>
<KuiFlexItem><div>Four</div></KuiFlexItem>
<KuiFlexItem><div>Five</div></KuiFlexItem>
<KuiFlexItem><div>Six</div></KuiFlexItem>
<KuiFlexItem><div>Seven</div></KuiFlexItem>
</KuiFlexGrid>
</div>
);

View file

@ -0,0 +1,18 @@
import React from 'react';
import {
KuiFlexGroup,
KuiFlexItem,
} from '../../../../components';
export default () => (
<KuiFlexGroup>
<KuiFlexItem>Content grid item</KuiFlexItem>
<KuiFlexItem>
<p>Another content grid item</p>
<br/>
<br/>
<p>Note how both of these are the same width and height despite having different content?</p>
</KuiFlexItem>
</KuiFlexGroup>
);

View file

@ -0,0 +1,15 @@
import React from 'react';
import {
KuiFlexGroup,
KuiFlexItem,
} from '../../../../components';
export default () => (
<div>
<KuiFlexGroup>
<KuiFlexItem grow={false}>This item wont grow</KuiFlexItem>
<KuiFlexItem>But this item will.</KuiFlexItem>
</KuiFlexGroup>
</div>
);

View file

@ -0,0 +1,57 @@
import React from 'react';
import {
KuiFlexGroup,
KuiFlexItem,
} from '../../../../components';
export default () => (
<div>
<KuiFlexGroup gutterSize="none">
<KuiFlexItem>None</KuiFlexItem>
<KuiFlexItem>None</KuiFlexItem>
<KuiFlexItem>None</KuiFlexItem>
<KuiFlexItem>None</KuiFlexItem>
</KuiFlexGroup>
<br/>
<br/>
<KuiFlexGroup gutterSize="small">
<KuiFlexItem>Small</KuiFlexItem>
<KuiFlexItem>Small</KuiFlexItem>
<KuiFlexItem>Small</KuiFlexItem>
<KuiFlexItem>Small</KuiFlexItem>
</KuiFlexGroup>
<br/>
<br/>
<KuiFlexGroup gutterSize="medium">
<KuiFlexItem>Medium</KuiFlexItem>
<KuiFlexItem>Medium</KuiFlexItem>
<KuiFlexItem>Medium</KuiFlexItem>
<KuiFlexItem>Medium</KuiFlexItem>
</KuiFlexGroup>
<br/>
<br/>
<KuiFlexGroup gutterSize="large">
<KuiFlexItem>Large (default)</KuiFlexItem>
<KuiFlexItem>Large (default)</KuiFlexItem>
<KuiFlexItem>Large (default)</KuiFlexItem>
<KuiFlexItem>Large (default)</KuiFlexItem>
</KuiFlexGroup>
<br/>
<br/>
<KuiFlexGroup gutterSize="extraLarge">
<KuiFlexItem>Extra Large</KuiFlexItem>
<KuiFlexItem>Extra Large</KuiFlexItem>
<KuiFlexItem>Extra Large</KuiFlexItem>
<KuiFlexItem>Extra Large</KuiFlexItem>
</KuiFlexGroup>
</div>
);

View file

@ -0,0 +1,16 @@
import React from 'react';
import {
KuiFlexGroup,
KuiFlexItem,
} from '../../../../components';
export default () => (
<KuiFlexGroup>
<KuiFlexItem>One</KuiFlexItem>
<KuiFlexItem>Two</KuiFlexItem>
<KuiFlexItem>Three</KuiFlexItem>
<KuiFlexItem>Four</KuiFlexItem>
<KuiFlexItem>Five</KuiFlexItem>
</KuiFlexGroup>
);

View file

@ -0,0 +1,35 @@
import React from 'react';
import {
KuiFlexGroup,
KuiFlexItem,
} from '../../../../components';
export default () => (
<div>
<KuiFlexGroup justifyContent="spaceBetween">
<KuiFlexItem grow={false}>One here on the left</KuiFlexItem>
<KuiFlexItem grow={false}>The other over here on the right.</KuiFlexItem>
</KuiFlexGroup>
<br/><br/>
<KuiFlexGroup justifyContent="spaceAround">
<KuiFlexItem grow={false}>I&rsquo;m a single centered item!</KuiFlexItem>
</KuiFlexGroup>
<br/><br/>
<KuiFlexGroup alignItems="center">
<KuiFlexItem grow={false}>
<div>
<p>I</p>
<p>am</p>
<p>really</p>
<p>tall</p>
</div>
</KuiFlexItem>
<KuiFlexItem>I am vertically centered!</KuiFlexItem>
</KuiFlexGroup>
</div>
);

View file

@ -0,0 +1,25 @@
import React from 'react';
import {
KuiFlexGroup,
KuiFlexItem,
KuiFlexGrid,
} from '../../../../components';
export default () => (
<div>
<KuiFlexGroup>
<KuiFlexItem grow={false}>Group One</KuiFlexItem>
<KuiFlexItem grow={false}>
<div>Group Two</div>
<br/><br/>
<KuiFlexGrid columns={3}>
<KuiFlexItem>Nested Grid One</KuiFlexItem>
<KuiFlexItem>Nested Grid Two</KuiFlexItem>
<KuiFlexItem>Nested Grid Three</KuiFlexItem>
<KuiFlexItem>Nested Grid Four</KuiFlexItem>
</KuiFlexGrid>
</KuiFlexItem>
</KuiFlexGroup>
</div>
);

View file

@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`KuiFlexGrid is rendered 1`] = `
<div
aria-label="aria-label"
class="kuiFlexGrid kuiFlexGrid--gutterLarge kuiFlexGrid--thirds testClass1 testClass2"
data-test-subj="test subject string"
/>
`;

View file

@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`KuiFlexGroup is rendered 1`] = `
<div
aria-label="aria-label"
class="kuiFlexGroup kuiFlexGroup--gutterLarge testClass1 testClass2"
data-test-subj="test subject string"
/>
`;

View file

@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`KuiFlexItem is rendered 1`] = `
<div
aria-label="aria-label"
class="kuiFlexItem testClass1 testClass2"
data-test-subj="test subject string"
/>
`;

View file

@ -0,0 +1,54 @@
.kuiFlexGrid {
display: flex;
flex-wrap: wrap;
margin-bottom: 0;
> .kuiFlexItem {
flex-grow: 0;
&.kuiFlexItem--flexGrowZero {
flex-grow: 0 !important;
flex-basis: auto !important;
}
}
}
$gutterTypes: (
gutterSmall: $kuiSizeS,
gutterMedium: $kuiSize,
gutterLarge: $kuiSizeL,
gutterXLarge: $kuiSizeXL,
);
$fractions: (
fourths: 25%,
thirds: 33.3%,
halves: 50%,
);
@each $gutterName, $gutterSize in $gutterTypes {
$halfGutterSize: $gutterSize * 0.5;
/**
* Uncouple the gutter margin from the column widths to support cases where we use a FlexGrid
* without columns.
*/
.kuiFlexGrid--#{$gutterName} {
> .kuiFlexItem {
margin: $halfGutterSize;
}
}
@each $fraction, $percentage in $fractions {
.kuiFlexGrid--#{$gutterName} {
margin: -$halfGutterSize;
align-items: stretch;
&.kuiFlexGrid--#{$fraction} {
> .kuiFlexItem {
flex-basis: calc(#{$percentage} - #{$gutterSize});
}
}
}
}
}

View file

@ -0,0 +1,62 @@
.kuiFlexGroup {
display: flex;
align-items: stretch;
.kuiFlexItem {
flex-grow: 1;
flex-basis: 0;
}
// Gutter Sizes
&.kuiFlexGroup--gutterSmall > .kuiFlexItem + .kuiFlexItem {
margin-left: $kuiSizeS;
}
&.kuiFlexGroup--gutterMedium > .kuiFlexItem + .kuiFlexItem {
margin-left: $kuiSize;
}
&.kuiFlexGroup--gutterLarge > .kuiFlexItem + .kuiFlexItem {
margin-left: $kuiSizeL;
}
&.kuiFlexGroup--gutterExtraLarge > .kuiFlexItem + .kuiFlexItem {
margin-left: $kuiSizeXXL;
}
// Justify the grid
&.kuiFlexGroup--justifyContentSpaceBetween {
justify-content: space-between;
}
&.kuiFlexGroup--justifyContentSpaceAround {
justify-content: space-around;
}
&.kuiFlexGroup--justifyContentCenter {
justify-content: center;
}
&.kuiFlexGroup--justifyContentFlexEnd {
justify-content: flex-end;
}
// Align Items
&.kuiFlexGroup--alignItemsStart {
align-items: flex-start;
}
&.kuiFlexGroup--alignItemsCenter {
align-items: center;
}
&.kuiFlexGroup--alignItemsEnd {
align-items: flex-end;
}
}
@include screenXSmall {
.kuiFlexGroup {
flex-wrap: wrap;
}
}

View file

@ -0,0 +1,26 @@
/**
* 1. Allow KuiPanels to expand to fill the item.
*/
.kuiFlexItem {
display: flex; /* 1 */
flex-direction: column; /* 1 */
/*
* 1. We need the extra specificity here to override the FlexGroup > FlexItem styles.
* 2. FlexItem can be manually set to not grow if needed.
*/
&.kuiFlexItem--flexGrowZero { /* 1 */
flex-grow: 0; /* 2 */
flex-basis: auto; /* 2 */
}
}
// On mobile we force them to stack and act the same.
@include screenXSmall {
.kuiFlexItem {
width: 100% !important;
flex-basis: 100% !important;
margin-left: 0 !important;
margin-bottom: $kuiSize !important;
}
}

View file

@ -0,0 +1,3 @@
@import 'flex_group';
@import 'flex_grid';
@import 'flex_item';

View file

@ -0,0 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
const gutterSizeToClassNameMap = {
none: '',
small: 'kuiFlexGrid--gutterSmall',
medium: 'kuiFlexGrid--gutterMedium',
large: 'kuiFlexGrid--gutterLarge',
extraLarge: 'kuiFlexGrid--gutterXLarge',
};
export const GUTTER_SIZES = Object.keys(gutterSizeToClassNameMap);
const columnsToClassNameMap = {
0: 'kuiFlexGrid--wrap',
2: 'kuiFlexGrid--halves',
3: 'kuiFlexGrid--thirds',
4: 'kuiFlexGrid--fourths',
};
export const COLUMNS = Object.keys(columnsToClassNameMap).map(columns => parseInt(columns, 10));
export const KuiFlexGrid = ({ children, className, gutterSize, columns, ...rest }) => {
const classes = classNames(
'kuiFlexGrid',
gutterSizeToClassNameMap[gutterSize],
columnsToClassNameMap[columns],
className
);
return (
<div
className={classes}
{...rest}
>
{children}
</div>
);
};
KuiFlexGrid.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
gutterSize: PropTypes.oneOf(GUTTER_SIZES),
columns: PropTypes.oneOf(COLUMNS).isRequired,
};
KuiFlexGrid.defaultProps = {
gutterSize: 'large',
columns: 0,
};

View file

@ -0,0 +1,16 @@
import React from 'react';
import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';
import { KuiFlexGrid } from './flex_grid';
describe('KuiFlexGrid', () => {
test('is rendered', () => {
const component = render(
<KuiFlexGrid columns={3} {...requiredProps} />
);
expect(component)
.toMatchSnapshot();
});
});

View file

@ -0,0 +1,65 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
const gutterSizeToClassNameMap = {
none: '',
small: 'kuiFlexGroup--gutterSmall',
medium: 'kuiFlexGroup--gutterMedium',
large: 'kuiFlexGroup--gutterLarge',
extraLarge: 'kuiFlexGroup--gutterExtraLarge',
};
export const GUTTER_SIZES = Object.keys(gutterSizeToClassNameMap);
const alignItemsToClassNameMap = {
stretch: '',
flexStart: 'kuiFlexGroup--alignItemsStart',
flexEnd: 'kuiFlexGroup--alignItemsEnd',
center: 'kuiFlexGroup--alignItemsCenter',
};
export const ALIGN_ITEMS = Object.keys(alignItemsToClassNameMap);
const justifyContentToClassNameMap = {
flexStart: '',
flexEnd: 'kuiFlexGroup--justifyContentFlexEnd',
center: 'kuiFlexGroup--justifyContentCenter',
spaceBetween: 'kuiFlexGroup--justifyContentSpaceBetween',
spaceAround: 'kuiFlexGroup--justifyContentSpaceAround',
};
export const JUSTIFY_CONTENTS = Object.keys(justifyContentToClassNameMap);
export const KuiFlexGroup = ({ children, className, gutterSize, alignItems, justifyContent, ...rest }) => {
const classes = classNames(
'kuiFlexGroup',
gutterSizeToClassNameMap[gutterSize],
alignItemsToClassNameMap[alignItems],
justifyContentToClassNameMap[justifyContent],
className
);
return (
<div
className={classes}
{...rest}
>
{children}
</div>
);
};
KuiFlexGroup.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
gutterSize: PropTypes.oneOf(GUTTER_SIZES),
alignItems: PropTypes.oneOf(ALIGN_ITEMS),
justifyContent: PropTypes.oneOf(JUSTIFY_CONTENTS),
};
KuiFlexGroup.defaultProps = {
gutterSize: 'large',
alignItems: 'stretch',
justifyContent: 'flexStart',
};

View file

@ -0,0 +1,16 @@
import React from 'react';
import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';
import { KuiFlexGroup } from './flex_group';
describe('KuiFlexGroup', () => {
test('is rendered', () => {
const component = render(
<KuiFlexGroup {...requiredProps} />
);
expect(component)
.toMatchSnapshot();
});
});

View file

@ -0,0 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
export const KuiFlexItem = ({ children, className, grow, ...rest }) => {
const classes = classNames(
'kuiFlexItem',
{
'kuiFlexItem--flexGrowZero': !grow,
},
className
);
return (
<div
className={classes}
{...rest}
>
{children}
</div>
);
};
KuiFlexItem.propTypes = {
children: PropTypes.node,
grow: PropTypes.bool,
};
KuiFlexItem.defaultProps = {
grow: true,
};

View file

@ -0,0 +1,16 @@
import React from 'react';
import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';
import { KuiFlexItem } from './flex_item';
describe('KuiFlexItem', () => {
test('is rendered', () => {
const component = render(
<KuiFlexItem {...requiredProps} />
);
expect(component)
.toMatchSnapshot();
});
});

View file

@ -0,0 +1,11 @@
export {
KuiFlexGroup,
} from './flex_group';
export {
KuiFlexGrid,
} from './flex_grid';
export {
KuiFlexItem,
} from './flex_item';

View file

@ -59,6 +59,12 @@ export {
KuiExpressionItemPopover,
} from './expression';
export {
KuiFlexGroup,
KuiFlexGrid,
KuiFlexItem,
} from './flex';
export {
KuiFieldGroup,
KuiFieldGroupSection,

View file

@ -24,6 +24,7 @@
@import "column/index";
@import "event/index";
@import "expression/index";
@import "flex/index";
@import "form/index";
@import "form_layout/index";
@import "gallery/index";

View file

@ -1 +1,2 @@
@import 'responsive';
@import 'global_mixins';

View file

@ -0,0 +1,9 @@
// Responsiveness
$breakpoints: ("small": 768px) !default;
@mixin screenXSmall {
@media only screen and (max-width: map-get($breakpoints, "small")) {
@content;
}
}

View file

@ -6,6 +6,7 @@
// coming from when looking inside the individual component files. Any component local
// variables should be declared at the top of those documents prefixed with $componentName.
@import 'size';
@import 'colors';
@import 'font';
@import 'timing';

View file

@ -0,0 +1,8 @@
$kuiSize: 16px;
$kuiSizeXS: $kuiSize * .25;
$kuiSizeS: $kuiSize * .5;
$kuiSizeM: $kuiSize * .75;
$kuiSizeL: $kuiSize * 1.5;
$kuiSizeXL: $kuiSize * 2;
$kuiSizeXXL: $kuiSize * 2.5;