Skip to content

Commit

Permalink
Merge pull request #69 from priley86/wizard
Browse files Browse the repository at this point in the history
feat(wizard): adds the pf wizard and modal components
  • Loading branch information
priley86 authored Dec 8, 2017
2 parents 30409e1 + 160bfc8 commit 14514f3
Show file tree
Hide file tree
Showing 38 changed files with 3,052 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/components/Modal/InnerComponents/CustomModalDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* CustomModalDialog creates custom ReactBootstrap ModalDialog
* https://github.com/react-bootstrap/react-bootstrap/blob/master/src/ModalDialog.js
*
* This extends ModalDialog and 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',
};

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 = {
/** 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,
};

export default bsClass(
'modal',
bsSizes([Size.LARGE, Size.SMALL], CustomModalDialog),
);
17 changes: 17 additions & 0 deletions src/components/Modal/Modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import CustomModalDialog from './InnerComponents/CustomModalDialog';
import { Modal as BsModal } from 'react-bootstrap';

/**
* Modal Component for Patternfly React
*/
class Modal extends BsModal {
render() {
return super.render();
}
}

Modal.defaultProps = Object.assign(BsModal.defaultProps, {
dialogComponentClass: CustomModalDialog,
});

export default Modal;
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 />),
);
131 changes: 131 additions & 0 deletions src/components/Modal/__mocks__/mockAboutModalManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React from 'react';
import { Button } from '../../Button';
import { Icon } from '../../Icon';
import { 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
contentClassName="about-modal-pf"
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
contentClassName="about-modal-pf"
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 14514f3

Please sign in to comment.