Skip to content

Commit

Permalink
Merge pull request #91 from contentful/refactor-modal-to-ts
Browse files Browse the repository at this point in the history
Refactor Modal to TS
  • Loading branch information
suevalov committed Feb 14, 2019
2 parents 89b1c11 + b6b83a2 commit 1277679
Show file tree
Hide file tree
Showing 21 changed files with 347 additions and 444 deletions.
124 changes: 6 additions & 118 deletions packages/forma-36-react-components/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
/// <reference path="./dist/components/FormLabel/FormLabel.d.ts" />
/// <reference path="./dist/components/Form/FieldGroup/FieldGroup.d.ts" />
/// <reference path="./dist/components/Form/Form/Form.d.ts" />
/// <reference path="./dist/components/Modal/Modal/Modal.d.ts" />
/// <reference path="./dist/components/Modal/ModalConfirm/ModalConfirm.d.ts" />

import * as React from 'react';

Expand Down Expand Up @@ -51,6 +53,8 @@ import ControlledInputFieldComponent from './dist/components/ControlledInputFiel
import FormLabelComponent from './dist/components/FormLabel/FormLabel';
import FieldGroupComponent from './dist/components/Form/FieldGroup/FieldGroup';
import FormComponent from './dist/components/Form/Form/Form';
import ModalComponent from './dist/components/Modal/Modal/Modal';
import ModalConfirmComponent from './dist/components/Modal/ModalConfirm/ModalConfirm';

export const Button: typeof ButtonComponent;
export const Spinner: typeof SpinnerComponent;
Expand All @@ -77,6 +81,8 @@ export const ControlledInputField: typeof ControlledInputFieldComponent;
export const FormLabel: typeof FormLabelComponent;
export const FieldGroup: typeof FieldGroupComponent;
export const Form: typeof FormComponent;
export const Modal: typeof ModalComponent;
export const ModalConfirm: typeof ModalConfirmComponent;

export interface CopyButtonProps {
extraClassNames?: string;
Expand Down Expand Up @@ -253,125 +259,7 @@ export interface ListItemProps {
export class ListItem extends React.Component<ListItemProps, any> {
render(): JSX.Element;
}
export type ModalPosition = any | any;

export type ModalTopOffset = string | number;

export type ModalSize = any | any | any | number | string;

export type ModalChildren = React.ReactNode | ((...args: any[]) => any);

export interface ModalProps {
/**
* When true, the dialog is shown.
*/
isShown: boolean;
/**
* Function that will be called when the exit is complete.
*/
onClose: (...args: any[]) => any;
/**
* Function that will be called when the enter is complete.
*/
onAfterOpen?: (...args: any[]) => any;
/**
* Boolean indicating if clicking the overlay should close the overlay.
*/
shouldCloseOnOverlayClick?: boolean;
/**
* Boolean indicating if pressing the esc key should close the overlay.
*/
shouldCloseOnEscapePress?: boolean;
/**
* Boolean indicating if modal is centered
*/
position?: ModalPosition;
/**
* Top offset if position is ModalPositions.TOP
*/
topOffset?: ModalTopOffset;
/**
* Modal title that is used in header
*/
title?: string;
/**
* Size of the modal window
*/
size?: ModalSize;
/**
* Are modals highter that viewerport allowed
*/
allowHeightOverflow?: boolean;
extraClassNames?: string;
testId?: string;
children: ModalChildren;
}

export class Modal extends React.Component<ModalProps, any> {
render(): JSX.Element;
}
export type ModalConfirmIntent = 'primary' | 'positive' | 'negative';

export type ModalConfirmSize = any | any | any | number | string;

export interface ModalConfirmProps {
/**
* When true, the dialog is shown.
*/
isShown: boolean;
/**
* Function that will be called when the confirm button is clicked. This does not close the ModalConfirm.
*/
onConfirm: (...args: any[]) => any;
/**
* Function that will be called when the cancel button is clicked. This does not close the ModalConfirm.
*/
onCancel: (...args: any[]) => any;
/**
* Modal title that is used in header
*/
title?: string;
/**
* Label of the confirm button
*/
confirmLabel?: string;
/**
* Label of the cancel button
*/
cancelLabel?: string;
/**
* The intent of the ModalConfirm. Used for the Button.
*/
intent?: ModalConfirmIntent;
/**
* Size of the modal window
*/
size?: ModalConfirmSize;
/**
* Boolean indicating if clicking the overlay should close the overlay.
*/
shouldCloseOnOverlayClick?: boolean;
/**
* Boolean indicating if pressing the esc key should close the overlay.
*/
shouldCloseOnEscapePress?: boolean;
/**
* When true, the confirm button is set to disabled.
*/
isConfirmDisabled?: boolean;
/**
* When true, the confirm button is set to loading.
*/
isConfirmLoading?: boolean;
testId?: string;
confirmTestId?: string;
cancelTestId?: string;
children: React.ReactNode;
}

export class ModalConfirm extends React.Component<ModalConfirmProps, any> {
render(): JSX.Element;
}
export interface ContentProps {
testId?: string;
extraClassNames?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { storiesOf, StoryDecorator } from '@storybook/react';
import { text, boolean, select } from '@storybook/addon-knobs';
import { host } from 'storybook-host';
import { withInfo } from '@storybook/addon-info';
Expand Down Expand Up @@ -27,7 +27,7 @@ storiesOf('Components|Modal', module)
cropMarks: false,
}),
)
.addDecorator(StateDecorator(store))
.addDecorator(StateDecorator(store) as StoryDecorator)
.add(
'default',
withInfo()(() => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import cn from 'classnames';
import ReactModal from 'react-modal';
import ModalHeader from '../ModalHeader';
import ModalContent from '../ModalContent';
import ModalControls from '../ModalControls';
import styles from './Modal.css';

const styles = require('./Modal.css');

const ModalPositions = {
CENTER: 'center',
TOP: 'top',
CENTER: 'center' as 'center',
TOP: 'top' as 'top',
};

export const ModalSizes = {
MEDIUM: 'medium',
SMALL: 'small',
LARGE: 'large',
MEDIUM: 'medium' as 'medium',
SMALL: 'small' as 'small',
LARGE: 'large' as 'large',
};

const ModalSizesMapper = {
Expand All @@ -24,7 +24,59 @@ const ModalSizesMapper = {
[ModalSizes.LARGE]: '700px',
};

class Modal extends React.Component {
export type ModalSizeType = 'small' | 'medium' | 'large' | string | number;

interface ModalProps {
/**
* When true, the dialog is shown.
*/
isShown: boolean;

/**
* Function that will be called when the exit is complete.
*/
onClose: Function;

/**
* Function that will be called when the enter is complete.
*/
onAfterOpen?: Function;
/**
* Boolean indicating if clicking the overlay should close the overlay.
*/
shouldCloseOnOverlayClick?: boolean;
/**
* Boolean indicating if pressing the esc key should close the overlay.
*/
shouldCloseOnEscapePress?: boolean;
/**
* Boolean indicating if modal is centered
*/
position?: 'center' | 'top';
/**
Top offset if position is 'top'
*/
topOffset?: number | string;
/**
Modal title that is used in header
*/
title?: string;
/**
Size of the modal window
*/
size?: ModalSizeType;
/**
* Are modals highter that viewerport allowed
*/
allowHeightOverflow?: boolean;
extraClassNames?: string;
testId?: string;

// eslint-disable-next-line
children: any;
}

export class Modal extends Component<ModalProps> {
static Positions = ModalPositions;

static Sizes = ModalSizes;
Expand All @@ -35,69 +87,13 @@ class Modal extends React.Component {

static Controls = ModalControls;

static propTypes = {
/**
* When true, the dialog is shown.
*/
isShown: PropTypes.bool.isRequired,

/**
* Function that will be called when the exit is complete.
*/
onClose: PropTypes.func.isRequired,

/**
* Function that will be called when the enter is complete.
*/
onAfterOpen: PropTypes.func,
/**
* Boolean indicating if clicking the overlay should close the overlay.
*/
shouldCloseOnOverlayClick: PropTypes.bool,
/**
* Boolean indicating if pressing the esc key should close the overlay.
*/
shouldCloseOnEscapePress: PropTypes.bool,
/**
* Boolean indicating if modal is centered
*/
position: PropTypes.oneOf([ModalPositions.CENTER, ModalPositions.TOP]),
/**
Top offset if position is ModalPositions.TOP
*/
topOffset: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
Modal title that is used in header
*/
title: PropTypes.string,
/**
Size of the modal window
*/
size: PropTypes.oneOfType([
PropTypes.oneOf([ModalSizes.MEDIUM, ModalSizes.LARGE, ModalSizes.SMALL])
.isRequired,
PropTypes.number.isRequired,
PropTypes.string.isRequired,
]),
/**
* Are modals highter that viewerport allowed
*/
allowHeightOverflow: PropTypes.bool,

extraClassNames: PropTypes.string,
testId: PropTypes.string,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
};

static defaultProps = {
shouldCloseOnEscapePress: true,
shouldCloseOnOverlayClick: true,
position: ModalPositions.CENTER,
position: 'center',
testId: 'cf-ui-modal',
title: undefined,
extraClassNames: undefined,
topOffset: '50px',
size: ModalSizes.MEDIUM,
size: 'medium',
allowHeightOverflow: false,
onAfterOpen: () => {},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,25 @@ exports[`can be controlled 1`] = `
}
}
>
<Header
<ModalHeader
onClose={[Function]}
testId="cf-ui-modal-header"
title="Hello"
/>
<Content
<ModalContent
testId="cf-ui-modal-content"
>
Content
</Content>
<Controls
</ModalContent>
<ModalControls
testId="cf-ui-modal-controls"
>
<button
type="button"
>
Click on me
</button>
</Controls>
</ModalControls>
</div>
</ReactModalMock>
`;
Expand Down Expand Up @@ -109,16 +109,16 @@ exports[`renders the component 1`] = `
}
}
>
<Header
<ModalHeader
onClose={[Function]}
testId="cf-ui-modal-header"
title="Title"
/>
<Content
<ModalContent
testId="cf-ui-modal-content"
>
Content
</Content>
</ModalContent>
</div>
</ReactModalMock>
`;
Expand Down Expand Up @@ -166,11 +166,11 @@ exports[`renders the component without title 1`] = `
}
}
>
<Content
<ModalContent
testId="cf-ui-modal-content"
>
Content
</Content>
</ModalContent>
</div>
</ReactModalMock>
`;
Loading

0 comments on commit 1277679

Please sign in to comment.