Skip to content

Commit

Permalink
Fixes liferay#1829 - Add Modal.Body, Modal.Footer, Modal.Header and s…
Browse files Browse the repository at this point in the history
…implifies the use of component
  • Loading branch information
matuzalemsteles authored and diegonvs committed May 27, 2019
1 parent 53a8eb9 commit ab9de5e
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 285 deletions.
27 changes: 27 additions & 0 deletions packages/clay-modal/src/Body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* © 2019 Liferay, Inc. <https://liferay.com>
*
* SPDX-License-Identifier: BSD-3-Clause
*/

import classNames from 'classnames';
import React, {FunctionComponent, HTMLAttributes} from 'react';

export interface BodyProps extends HTMLAttributes<HTMLDivElement> {
/**
* Url to place an iframe in the body of the modal.
*/
url?: string;
}

const Body: FunctionComponent<BodyProps> = ({children, url}) => (
<div
className={classNames('modal-body', {
'modal-body-iframe': url,
})}
>
{url ? <iframe src={url} title={url} /> : children}
</div>
);

export default Body;
206 changes: 0 additions & 206 deletions packages/clay-modal/src/ClayModal.tsx

This file was deleted.

27 changes: 27 additions & 0 deletions packages/clay-modal/src/Context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* © 2019 Liferay, Inc. <https://liferay.com>
*
* SPDX-License-Identifier: BSD-3-Clause
*/

import {createContext} from 'react';
import {Status} from './types';

export interface IContext {
/**
* Callback called to close the modal.
*/
onClose: () => void;

/**
* The path to the SVG spritemap file containing the icons.
*/
spritemap?: string;

/**
* Status messages.
*/
status?: Status;
}

export default createContext({} as IContext);
72 changes: 11 additions & 61 deletions packages/clay-modal/src/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,70 +4,20 @@
* SPDX-License-Identifier: BSD-3-Clause
*/

import classNames from 'classnames';
import React, {FunctionComponent, HTMLAttributes} from 'react';
import warning from 'warning';
import React, {FunctionComponent} from 'react';

export interface FooterContainerProps extends HTMLAttributes<HTMLDivElement> {
position?: number;
export interface FooterProps {
first?: React.ReactElement;
last?: React.ReactElement;
middle?: React.ReactElement;
}

const ButtonWrap: FunctionComponent<HTMLAttributes<HTMLDivElement>> = ({
children,
}) => <div className="btn-group-item">{children}</div>;

const FooterContainer: FunctionComponent<FooterContainerProps> = ({
children,
position,
}) => (
<div
className={classNames({
'modal-item-first': position === 0,
'modal-item-last': position === 1,
})}
>
<div className="btn-group">
{React.Children.map(children, (child, i) =>
React.cloneElement(<ButtonWrap>{child}</ButtonWrap>, {key: i})
)}
</div>
const Footer: FunctionComponent<FooterProps> = ({first, middle, last}) => (
<div className="modal-footer">
<div className="modal-item-first">{first && first}</div>
<div className="modal-item">{middle && middle}</div>
<div className="modal-item-last">{last && last}</div>
</div>
);

interface FooterProps {
children: React.ReactElement<FunctionComponent<FooterContainerProps>>;
}

/**
* Handles the childrens of the footer to format the markup and add
* the necessary classNames.
*/
const Footer: FunctionComponent<FooterProps> = ({children}) => {
let childrens = children;
if (children.type && (children.type as any) === React.Fragment) {
childrens = children.props.children;
}

warning(
(children.type as any) === React.Fragment ||
typeof (children.type as any) === 'function',
'ClayModal -> Wrap the `<FooterContainer />` elements inside a Fragment to work as expected.'
);

const count = React.Children.count(childrens);

warning(
count <= 2,
`ClayModal -> props \`renderFooter\` has received more ${count} elements, only 2 is allowed, works fine use only 2 elements of <FooterContainer />`
);

return (
<div className="modal-footer">
{React.Children.map(childrens, (child: any, i) =>
React.cloneElement(child, {position: i})
)}
</div>
);
};

export {Footer, FooterContainer};
export default Footer;
44 changes: 44 additions & 0 deletions packages/clay-modal/src/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* © 2019 Liferay, Inc. <https://liferay.com>
*
* SPDX-License-Identifier: BSD-3-Clause
*/

import Button from '@clayui/button';
import Context from './Context';
import Icon from '@clayui/icon';
import React, {FunctionComponent, HTMLAttributes, useContext} from 'react';

export type HeaderProps = HTMLAttributes<HTMLDivElement>;

const ICON_MAP = {
danger: 'exclamation-full',
info: 'info-circle',
success: 'check-circle',
warning: 'question-circle-full',
};

const Header: FunctionComponent<HeaderProps> = ({children}) => {
const {onClose, spritemap, status} = useContext(Context);

return (
<div className="modal-header">
{status && (
<div className="modal-title-indicator">
<Icon spritemap={spritemap} symbol={ICON_MAP[status]} />
</div>
)}
<div className="modal-title">{children}</div>
<Button
aria-label="close"
className="close"
displayType="unstyled"
onClick={onClose}
>
<Icon spritemap={spritemap} symbol="times" />
</Button>
</div>
);
};

export default Header;
Loading

0 comments on commit ab9de5e

Please sign in to comment.