Skip to content
This repository was archived by the owner on Dec 9, 2021. It is now read-only.

Modal #26

Merged
merged 3 commits into from
Nov 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions src/constants/KeyCode.ts

This file was deleted.

47 changes: 20 additions & 27 deletions src/views/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import IStore from '../../stores/IStore';
import {Dispatch} from 'redux';
import IMetaReducerState from '../../stores/meta/IMetaReducerState';
import IUserReducerState from '../../stores/user/IUserReducerState';
import GeneralModalAsync from '../modals/GeneralModalAsync';
import GenericModalAsync from '../modals/GenericModalAsync';
import ModalAction from '../../stores/modal/ModalAction';
import ExampleFormModalAsync from '../modals/ExampleFormModalAsync';
import IAction from '../../stores/IAction';
import {IProps as GenericModalProps} from '../modals/GenericModal';

interface IState {}
interface IProps {}
Expand Down Expand Up @@ -39,7 +40,7 @@ class Home extends React.Component<IStateToProps & IDispatchToProps & IProps, IS
private _onClickPushExampleHandler: (event: React.MouseEvent<HTMLButtonElement>) => void = this._onClickPushExample.bind(this);
private _onClickOpenModalHandler: (event: React.MouseEvent<HTMLButtonElement>) => void = this._onClickOpenModal.bind(this);
private _onClickFormModalHandler: (event: React.MouseEvent<HTMLButtonElement>) => void = this._onClickFormModal.bind(this);
private _onAcceptHandler: (event: React.MouseEvent<HTMLButtonElement>) => void = this._onAccept.bind(this);
private _onAcceptHandler: (modalProps: GenericModalProps) => void = this._onAccept.bind(this);

public componentWillMount(): void {
this.props.setMeta({
Expand Down Expand Up @@ -88,46 +89,38 @@ class Home extends React.Component<IStateToProps & IDispatchToProps & IProps, IS
event.preventDefault();

const genericModal: JSX.Element = (
<GeneralModalAsync
modalData={{
message: (
<div>
<h3>{'Generic Modal'}</h3>
<p>{'Example of a generic modal. Used for simple messages.'}</p>
</div>
),
acceptLabel: 'Open Another Modal',
rejectLabel: 'Close',
}}
<GenericModalAsync
message={(
<div>
<h3>{'Generic Modal'}</h3>
<p>{'Example of a generic modal. Used for simple messages.'}</p>
</div>
)}
acceptLabel={'Open Another Modal'}
rejectLabel={'Close'}
onAccept={this._onAcceptHandler}
/>
);

this.props.addModal(genericModal);
}

private _onAccept(event: React.MouseEvent<HTMLButtonElement>): void {
event.preventDefault();

private _onAccept(modalProps: GenericModalProps): void {
const genericModal: JSX.Element = (
<GeneralModalAsync
modalData={{
message: (
<div>
<p>{'Handles opening multiple modals.'}</p>
</div>
),
acceptLabel: 'Ok',
}}
<GenericModalAsync
message={(
<div>
<p>{'Handles opening multiple modals.'}</p>
</div>
)}
acceptLabel={'Ok'}
/>
);

this.props.addModal(genericModal);
}

private _onClickFormModal(event: React.MouseEvent<HTMLButtonElement>): void {
event.preventDefault();

const formModal: JSX.Element = (
<ExampleFormModalAsync isRequired={true} />
);
Expand Down
83 changes: 83 additions & 0 deletions src/views/modals/BaseModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import * as React from 'react';
import {connect} from 'react-redux';
import {Dispatch} from 'redux';
import IAction from '../../stores/IAction';
import IStore from '../../stores/IStore';
import ModalAction from '../../stores/modal/ModalAction';
import KeyboardKeyEnum from '../../constants/KeyboardKeyEnum';
import * as classNames from 'classnames';

interface IProps {
isRequired?: boolean;
}
interface IState {}
interface IStateToProps {}
interface IDispatchToProps {
dispatch: (action: IAction<any>) => void;
}

const mapStateToProps = (state: IStore) => ({});
const mapDispatchToProps = (dispatch: Dispatch<IAction<any>>): IDispatchToProps => ({
dispatch,
});

type PropsUnion = IStateToProps & IDispatchToProps & IProps;

class BaseModal extends React.Component<PropsUnion, IState> {

public static defaultProps: Partial<PropsUnion> = {
isRequired: false,
};

public componentDidMount(): void {
if (!this.props.isRequired) {
global.window.addEventListener('keydown', this._onKeyDownModal);
}
}

public componentWillUnmount(): void {
if (!this.props.isRequired) {
global.window.removeEventListener('keydown', this._onKeyDownModal);
}
}

public render(): JSX.Element {
return (
<div
className="modal"
role="alert"
aria-live="polite"
>
<div
className={this._buildModalOverlayClassNames()}
onClick={this._onClickOverlay}
/>
{this.props.children}
</div>
);
}

private _onClickOverlay = (event: React.MouseEvent<HTMLElement>): void => {
if (!this.props.isRequired) {
this.props.dispatch(ModalAction.closeModal());
}
}

private _onKeyDownModal = (event: KeyboardEvent): void => {
if (event.key === KeyboardKeyEnum.ESCAPE) {
event.preventDefault();

this.props.dispatch(ModalAction.closeModal());
}
}

private _buildModalOverlayClassNames = (): string => {
return classNames({
'modal-overlay': true,
'modal-overlay_required': this.props.isRequired,
});
}

}

export default connect<IStateToProps, IDispatchToProps, IProps>(mapStateToProps, mapDispatchToProps)(BaseModal);
68 changes: 48 additions & 20 deletions src/views/modals/ExampleFormModal.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,58 @@
import * as React from 'react';
import {form2js} from 'form2js';
import withBaseModal, {TProps as BaseModelProps} from './withBaseModal';
import InputField from '../components/InputField';
import {connect} from 'react-redux';
import IAction from '../../stores/IAction';
import IStore from '../../stores/IStore';
import {Dispatch} from 'redux';
import ModalAction from '../../stores/modal/ModalAction';
import BaseModal from './BaseModal';

interface IProps extends BaseModelProps {
modalData: {};
export interface IProps {
isRequired: boolean;
data: any;
}
interface IState {}
interface IStateToProps {}
interface IDispatchToProps {
dispatch: (action: IAction<any>) => void;
}

const mapStateToProps = (state: IStore) => ({});
const mapDispatchToProps = (dispatch: Dispatch<IAction<any>>): IDispatchToProps => ({
dispatch,
});

type PropsUnion = IStateToProps & IDispatchToProps & IProps;

class ExampleFormModal extends React.Component<IProps, IState> {
class ExampleFormModal extends React.Component<PropsUnion, IState> {

public static defaultProps: Partial<PropsUnion> = {
isRequired: false,
};

private _formElement: HTMLFormElement = null;
private _onClickAcceptHandler: (event: React.MouseEvent<HTMLButtonElement>) => void = this._onClickAccept.bind(this);
private _onClickCloseHandler: (event: React.MouseEvent<HTMLButtonElement>) => void = this._onClickClose.bind(this);

public render(): JSX.Element {
return (
<section className="modal-content">
<h2 className="modal-header modal-header_left">{'Modal Form Title'}</h2>
<div className="modal-body">
{this._buildFormJsx()}
</div>
<div className="modal-footer modal-footer_stack">
<button onClick={this.props.closeModal}>
{'Cancel'}
</button>
<button onClick={this._onClickAcceptHandler}>
{'Accept'}
</button>
</div>
</section>
<BaseModal isRequired={this.props.isRequired}>
<section className="modal-content">
<h2 className="modal-header modal-header_left">{'Modal Form Title'}</h2>
<div className="modal-body">
{this._buildFormJsx()}
</div>
<div className="modal-footer modal-footer_stack">
<button onClick={this._onClickCloseHandler}>
{'Cancel'}
</button>
<button onClick={this._onClickAcceptHandler}>
{'Accept'}
</button>
</div>
</section>
</BaseModal>
);
}

Expand Down Expand Up @@ -119,12 +143,16 @@ class ExampleFormModal extends React.Component<IProps, IState> {

console.info(formData);

this.props.closeModal();
this._onClickClose();
} else {
this._formElement.classList.remove('u-validate');
}
}

private _onClickClose(event: React.MouseEvent<HTMLButtonElement> = null): void {
this.props.dispatch(ModalAction.closeModal());
}

}

export default withBaseModal(ExampleFormModal);
export default connect<IStateToProps, IDispatchToProps, IProps>(mapStateToProps, mapDispatchToProps)(ExampleFormModal);
43 changes: 0 additions & 43 deletions src/views/modals/GeneralModal.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions src/views/modals/GeneralModalAsync.tsx

This file was deleted.

Loading