diff --git a/src/components/Modal/CustomModalDialog.js b/src/components/Modal/CustomModalDialog.js
new file mode 100644
index 00000000000..e52c867e67c
--- /dev/null
+++ b/src/components/Modal/CustomModalDialog.js
@@ -0,0 +1,87 @@
+/**
+ * CustomModalDialog creates custom ReactBootstrap ModalDialog
+ * https://github.com/react-bootstrap/react-bootstrap/blob/master/src/ModalDialog.js
+ *
+ * Adds contentClassName prop for setting `modal-content` div's class
+ */
+import classNames from 'classnames';
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { utils } from 'react-bootstrap';
+
+const bsClass = utils.bootstrapUtils.bsClass;
+const bsSizes = utils.bootstrapUtils.bsSizes;
+const getClassSet = utils.bootstrapUtils.getClassSet;
+const prefix = utils.bootstrapUtils.prefix;
+const splitBsProps = utils.bootstrapUtils.splitBsProps;
+
+// React Bootstrap utils/StyleConfig Size is currently not exported
+const Size = {
+ LARGE: 'large',
+ SMALL: 'small',
+ XSMALL: 'xsmall',
+};
+
+const propTypes = {
+ /** A css class to apply to the Modal dialog DOM node. */
+ dialogClassName: PropTypes.string,
+ /** custom modal-content class added to the content DOM node */
+ contentClassName: PropTypes.string,
+ /** base modal class name */
+ className: PropTypes.string,
+ /** additional modal styles */
+ style: PropTypes.object,
+ /** Children nodes */
+ children: PropTypes.node,
+};
+
+class CustomModalDialog extends React.Component {
+ render() {
+ const {
+ dialogClassName,
+ contentClassName,
+ className,
+ style,
+ children,
+ ...props
+ } = this.props;
+ const [bsProps, elementProps] = splitBsProps(props);
+
+ const bsClassName = prefix(bsProps);
+
+ const modalStyle = { display: 'block', ...style };
+
+ const dialogClasses = {
+ ...getClassSet(bsProps),
+ [bsClassName]: false,
+ [prefix(bsProps, 'dialog')]: true,
+ };
+
+ return (
+
+ );
+ }
+}
+
+CustomModalDialog.propTypes = propTypes;
+
+export default bsClass(
+ 'modal',
+ bsSizes([Size.LARGE, Size.SMALL], CustomModalDialog),
+);
diff --git a/src/components/Modal/Modal.js b/src/components/Modal/Modal.js
new file mode 100644
index 00000000000..3d2fe9c8c83
--- /dev/null
+++ b/src/components/Modal/Modal.js
@@ -0,0 +1 @@
+export { Modal as default } from 'react-bootstrap';
diff --git a/src/components/Modal/Modal.stories.js b/src/components/Modal/Modal.stories.js
new file mode 100644
index 00000000000..79f7c75fb4e
--- /dev/null
+++ b/src/components/Modal/Modal.stories.js
@@ -0,0 +1,63 @@
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+import { withInfo } from '@storybook/addon-info';
+import { defaultTemplate } from '../../../storybook/decorators/storyTemplates';
+
+import {
+ MockModalManager,
+ basicExampleSource,
+} from './__mocks__/mockModalManager';
+
+import {
+ MockAboutModalManager,
+ aboutExampleSource,
+} from './__mocks__/mockAboutModalManager';
+
+const stories = storiesOf('Modal Overlay', module);
+
+const description = (
+
+ This component is based on React Bootstrap Modal component. See{' '}
+
+ React Bootstrap Docs
+ {' '}
+ for complete Modal component documentation.
+
+);
+
+stories.addDecorator(
+ defaultTemplate({
+ title: 'Modal Overlay',
+ documentationLink:
+ 'http://www.patternfly.org/pattern-library/forms-and-controls/modal-overlay/',
+ description: description,
+ }),
+);
+
+stories.add(
+ 'Basic example',
+ withInfo({
+ source: false,
+ propTablesExclude: [MockModalManager],
+ text: (
+
+
Story Source
+
{basicExampleSource}
+
+ ),
+ })(() => ),
+);
+
+stories.add(
+ 'About Modal',
+ withInfo({
+ source: false,
+ propTablesExclude: [MockAboutModalManager],
+ text: (
+
+
Story Source
+
{aboutExampleSource}
+
+ ),
+ })(() => ),
+);
diff --git a/src/components/Modal/__mocks__/mockAboutModalManager.js b/src/components/Modal/__mocks__/mockAboutModalManager.js
new file mode 100644
index 00000000000..2ceef8fb483
--- /dev/null
+++ b/src/components/Modal/__mocks__/mockAboutModalManager.js
@@ -0,0 +1,133 @@
+import React from 'react';
+import { Button } from '../../Button';
+import { Icon } from '../../Icon';
+import { CustomModalDialog, Modal } from '../index';
+import logo from 'patternfly/dist/img/logo-alt.svg';
+
+export class MockAboutModalManager extends React.Component {
+ constructor() {
+ super();
+ this.state = { showModal: false };
+ this.open = this.open.bind(this);
+ this.close = this.close.bind(this);
+ }
+ open() {
+ this.setState({ showModal: true });
+ }
+ close() {
+ this.setState({ showModal: false });
+ }
+ render() {
+ return (
+
+
+
+
+
+
+
+
+ Product Title
+
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+
+
+
+ Trademark and Copyright Information
+
+
+
+
+
+
+
+ );
+ }
+}
+
+export const aboutExampleSource = `
+
+
+
+
+
+
+
+ Product Title
+
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+ -
+ Label Version
+
+
+
+ Trademark and Copyright Information
+
+
+
+
+
+`;
diff --git a/src/components/Modal/__mocks__/mockModalManager.js b/src/components/Modal/__mocks__/mockModalManager.js
new file mode 100644
index 00000000000..928fabc885f
--- /dev/null
+++ b/src/components/Modal/__mocks__/mockModalManager.js
@@ -0,0 +1,146 @@
+import React from 'react';
+import { Button } from '../../Button';
+import { Icon } from '../../Icon';
+import { Modal } from '../index';
+
+export class MockModalManager extends React.Component {
+ constructor() {
+ super();
+ this.state = { showModal: false };
+ this.open = this.open.bind(this);
+ this.close = this.close.bind(this);
+ }
+ open() {
+ this.setState({ showModal: true });
+ }
+ close() {
+ this.setState({ showModal: false });
+ }
+ render() {
+ return (
+
+
+
+
+
+
+ Modal Overlay Title
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+export const basicExampleSource = `
+
+
+
+
+
+ Modal Overlay Title
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/components/Modal/index.js b/src/components/Modal/index.js
new file mode 100644
index 00000000000..40a3f87509b
--- /dev/null
+++ b/src/components/Modal/index.js
@@ -0,0 +1,2 @@
+export { default as CustomModalDialog } from './CustomModalDialog';
+export { default as Modal } from './Modal';
diff --git a/src/index.js b/src/index.js
index e41a0fd8f69..29e139903c1 100644
--- a/src/index.js
+++ b/src/index.js
@@ -9,6 +9,7 @@ export * from './components/Icon';
export * from './components/ListGroup';
export * from './components/ListView';
export * from './components/MenuItem';
+export * from './components/Modal';
export * from './components/OverlayTrigger';
export * from './components/Popover';
export * from './components/ToastNotification';