diff --git a/src/Layout/Layout.test.jsx b/src/Layout/Layout.test.jsx
new file mode 100644
index 0000000000..4a301c3f28
--- /dev/null
+++ b/src/Layout/Layout.test.jsx
@@ -0,0 +1,42 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import Layout from './index';
+
+function TestLayout(props) {
+ return (
+
+ first block
+ second block
+ third block
+
+ );
+}
+
+describe('', () => {
+ describe('correct rendering', () => {
+ it('renders correct number of children', () => {
+ const wrapper = mount();
+ const children = wrapper.find('.row div');
+ expect(children.length).toEqual(3);
+ });
+ it('renders correct number of children', () => {
+ const wrapper = mount();
+ const children = wrapper.find('.row div');
+ expect(children.at(0).hasClass(
+ 'col-xl-3 col-lg-4 col-md-auto col-sm-8 col-4 offset-xl-0 offset-lg-0 offset-md-0 offset-sm-0 offset-0',
+ )).toEqual(true);
+ });
+ it('renders although dimensions are incorrect', () => {
+ const wrapper = mount();
+ const children = wrapper.find('.row div');
+ expect(children.length).not.toEqual(0);
+ });
+ });
+});
diff --git a/src/Layout/README.md b/src/Layout/README.md
new file mode 100644
index 0000000000..d438190beb
--- /dev/null
+++ b/src/Layout/README.md
@@ -0,0 +1,29 @@
+---
+title: 'Layout'
+type: 'component'
+components:
+- Layout
+categories:
+- Layout
+status: 'New'
+designStatus: 'Done'
+devStatus: 'Done'
+---
+
+A wrapper component that allows to control the size of child blocks on different screen sizes.
+
+## Basic usage
+
+```jsx live
+
+ first block
+ second block
+ third block
+
+```
diff --git a/src/Layout/index.jsx b/src/Layout/index.jsx
index a03bc9a6f8..46fdbb553b 100644
--- a/src/Layout/index.jsx
+++ b/src/Layout/index.jsx
@@ -1,2 +1,92 @@
-export { default as Col } from 'react-bootstrap/Col';
-export { default as Row } from 'react-bootstrap/Row';
+import React from 'react';
+import Col from 'react-bootstrap/Col';
+import Row from 'react-bootstrap/Row';
+import PropTypes from 'prop-types';
+
+const COL_VALUES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 'auto'];
+const SIZES = ['xs', 'sm', 'md', 'lg', 'xl'];
+
+const LayoutElement = React.forwardRef((props, ref) =>
);
+
+const Layout = React.forwardRef(({ children, ...props }, ref) => {
+ const childrenLength = children.length;
+
+ const isValidDimensions = (dataList, validLength) => !dataList || dataList.length === validLength;
+ const errors = {};
+
+ const layout = React.Children.map(children, (child, index) => {
+ const newProps = { ...child.props };
+ SIZES.forEach(size => {
+ const sizeProps = props[size];
+ const { span = 0, offset = 0 } = (sizeProps && sizeProps[index]) || {};
+ if (errors[size] === undefined) {
+ errors[size] = false;
+ if (!isValidDimensions(sizeProps, childrenLength)) {
+ errors[size] = `${size} prop accepts array which length must be equal to the number of children.`;
+ }
+ }
+ newProps[size] = { span, offset };
+ });
+ newProps.ref = child.ref;
+ return React.createElement(Col, newProps, child.props.children);
+ });
+
+ Object.keys(errors).forEach(breakpoint => {
+ if (errors[breakpoint]) {
+ // eslint-disable-next-line no-console
+ console.error(errors[breakpoint]);
+ }
+ });
+
+ return (
+
+ {layout}
+
+ );
+});
+
+Layout.defaultProps = {
+ xs: undefined,
+ sm: undefined,
+ md: undefined,
+ lg: undefined,
+ xl: undefined,
+};
+
+Layout.propTypes = {
+ children: PropTypes.node.isRequired,
+ xs: PropTypes.arrayOf(PropTypes.shape({
+ span: PropTypes.oneOf(COL_VALUES).isRequired,
+ offset: PropTypes.oneOf(COL_VALUES),
+ })),
+ sm: PropTypes.arrayOf(PropTypes.shape({
+ span: PropTypes.oneOf(COL_VALUES).isRequired,
+ offset: PropTypes.oneOf(COL_VALUES),
+ })),
+ md: PropTypes.arrayOf(PropTypes.shape({
+ span: PropTypes.oneOf(COL_VALUES).isRequired,
+ offset: PropTypes.oneOf(COL_VALUES),
+ })),
+ lg: PropTypes.arrayOf(PropTypes.shape({
+ span: PropTypes.oneOf(COL_VALUES).isRequired,
+ offset: PropTypes.oneOf(COL_VALUES),
+ })),
+ xl: PropTypes.arrayOf(PropTypes.shape({
+ span: PropTypes.oneOf(COL_VALUES).isRequired,
+ offset: PropTypes.oneOf(COL_VALUES),
+ })),
+};
+
+const sizeDefaultProps = { span: [], offset: [] };
+
+SIZES.forEach(size => {
+ // eslint-disable-next-line react/default-props-match-prop-types
+ Layout.defaultProps[size] = sizeDefaultProps;
+});
+
+export {
+ Col,
+ Row,
+};
+Layout.Element = LayoutElement;
+export default Layout;
diff --git a/src/index.js b/src/index.js
index a84f2e736b..28892d7df7 100644
--- a/src/index.js
+++ b/src/index.js
@@ -24,7 +24,7 @@ export { default as CheckBoxGroup } from './CheckBoxGroup';
export { default as Chip } from './Chip';
export { default as CloseButton } from './CloseButton';
export { default as Container } from './Container';
-export { Col, Row } from './Layout';
+export { default as Layout, Col, Row } from './Layout';
export { default as Collapse } from './Collapse';
export { default as Collapsible } from './Collapsible';
export { default as Scrollable } from './Scrollable';