Skip to content

Commit

Permalink
feat(modal): adds the pf modal patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
priley86 committed Dec 7, 2017
1 parent 30409e1 commit a64a2cb
Show file tree
Hide file tree
Showing 7 changed files with 433 additions and 0 deletions.
87 changes: 87 additions & 0 deletions src/components/Modal/CustomModalDialog.js
Original file line number Diff line number Diff line change
@@ -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 (
<div
{...elementProps}
tabIndex="-1"
role="dialog"
style={modalStyle}
className={classNames(className, bsClassName)}
>
<div className={classNames(dialogClassName, dialogClasses)}>
<div
className={classNames(prefix(bsProps, 'content'), contentClassName)}
role="document"
>
{children}
</div>
</div>
</div>
);
}
}

CustomModalDialog.propTypes = propTypes;

export default bsClass(
'modal',
bsSizes([Size.LARGE, Size.SMALL], CustomModalDialog),
);
1 change: 1 addition & 0 deletions src/components/Modal/Modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Modal as default } from 'react-bootstrap';
63 changes: 63 additions & 0 deletions src/components/Modal/Modal.stories.js
Original file line number Diff line number Diff line change
@@ -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 = (
<p>
This component is based on React Bootstrap Modal component. See{' '}
<a href="https://react-bootstrap.github.io/components.html#modals">
React Bootstrap Docs
</a>{' '}
for complete Modal component documentation.
</p>
);

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: (
<div>
<h1>Story Source</h1>
<pre>{basicExampleSource}</pre>
</div>
),
})(() => <MockModalManager />),
);

stories.add(
'About Modal',
withInfo({
source: false,
propTablesExclude: [MockAboutModalManager],
text: (
<div>
<h1>Story Source</h1>
<pre>{aboutExampleSource}</pre>
</div>
),
})(() => <MockAboutModalManager />),
);
133 changes: 133 additions & 0 deletions src/components/Modal/__mocks__/mockAboutModalManager.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<Button bsStyle="primary" bsSize="large" onClick={this.open}>
Launch about modal
</Button>

<Modal
dialogComponentClass={CustomModalDialog}
contentClassName="about-modal-pf"
bsClass="modal"
show={this.state.showModal}
onHide={this.close}
>
<Modal.Header>
<button
className="close"
onClick={this.close}
aria-hidden="true"
aria-label="Close"
>
<Icon type="pf" name="close" />
</button>
</Modal.Header>
<Modal.Body>
<h1>Product Title</h1>
<div className="product-versions-pf">
<ul className="list-unstyled">
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
</ul>
</div>
<div className="trademark-pf">
Trademark and Copyright Information
</div>
</Modal.Body>
<Modal.Footer>
<img src={logo} alt="Patternfly Logo" />
</Modal.Footer>
</Modal>
</div>
);
}
}

export const aboutExampleSource = `
<Button bsStyle="primary" bsSize="large" onClick={this.open}>
Launch about modal
</Button>
<Modal
dialogComponentClass={CustomModalDialog}
contentClassName="about-modal-pf"
bsClass="modal"
show={this.state.showModal}
onHide={this.close}
>
<Modal.Header>
<button
className="close"
onClick={this.close}
aria-hidden="true"
aria-label="Close"
>
<Icon type="pf" name="close" />
</button>
</Modal.Header>
<Modal.Body>
<h1>Product Title</h1>
<div className="product-versions-pf">
<ul className="list-unstyled">
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
<li>
<strong>Label</strong> Version
</li>
</ul>
</div>
<div className="trademark-pf">Trademark and Copyright Information</div>
</Modal.Body>
<Modal.Footer>
<img src={logo} alt="Patternfly Logo" />
</Modal.Footer>
</Modal>
`;
Loading

0 comments on commit a64a2cb

Please sign in to comment.