Skip to content
Open
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
51 changes: 27 additions & 24 deletions src/Modal/ModalCloseButton.jsx → src/Modal/ModalCloseButton.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import {
useContext, ReactNode, ElementType, forwardRef, createElement,
} from 'react';
import classNames from 'classnames';
import ModalContext from './ModalContext';
import Button from '../Button';

const ModalCloseButton = React.forwardRef(({ as, children, ...props }, ref) => {
export interface ModalCloseButtonProps {
/** Specifies the base element */
as?: ElementType;
/** Specifies the content of the button */
children?: ReactNode;
/** Specifies class name to append to the base element */
className?: string;
/** Specifies the callback function when the close button is clicked */
onClick?: () => void;
[key: string]: any; // For spreading other props
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use ComponentWithAsProp or a similar helper to provide the actual type for other props, based on the as prop. But maybe it's not worth it for such a small, simple, mostly internal component.

}

const ModalCloseButton = forwardRef(({
as = Button,
children = null,
className,
onClick,
...props
}: ModalCloseButtonProps, ref: React.Ref<HTMLButtonElement>) => {
const { onClose } = useContext(ModalContext);
const type = as;
const componentProps = {
...props,
className: classNames('pgn__modal-close-button', props.className),
className: classNames('pgn__modal-close-button', className),
onClick: () => {
onClose();
if (props.onClick) {
props.onClick();
if (onClick) {
onClick();
}
},
ref,
};

// Use the non-jsx syntax to create this element so we can more
// finely control the component type (defaulted to Button via defaultProps)
return React.createElement(type, componentProps, children);
return createElement(type, componentProps, children);
});

ModalCloseButton.propTypes = {
/** Specifies the base element */
as: PropTypes.elementType,
/** Specifies the content of the button */
children: PropTypes.node,
/** Specifies class name to append to the base element */
className: PropTypes.string,
/** Specifies the callback function when the close button is clicked */
onClick: PropTypes.func,
};

ModalCloseButton.defaultProps = {
as: Button,
onClick: undefined,
className: undefined,
children: null,
};
ModalCloseButton.displayName = 'ModalCloseButton';

export default ModalCloseButton;
1 change: 0 additions & 1 deletion src/Modal/ModalDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import classNames from 'classnames';
import { useMediaQuery } from 'react-responsive';
import { useIntl } from 'react-intl';
import ModalLayer from './ModalLayer';
// @ts-ignore for now - this needs to be converted to TypeScript
import ModalCloseButton from './ModalCloseButton';
import ModalDialogHeader from './ModalDialogHeader';
// @ts-ignore for now - this needs to be converted to TypeScript
Expand Down
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export {
export { default as Hyperlink } from './Hyperlink';
export { default as Icon } from './Icon';
export { default as IconButton, IconButtonWithTooltip } from './IconButton';
export { default as ModalCloseButton } from './Modal/ModalCloseButton';
export { default as ModalContext } from './Modal/ModalContext';
export { default as ModalDialog } from './Modal/ModalDialog';
export { default as ModalLayer } from './Modal/ModalLayer';
Expand Down Expand Up @@ -109,8 +110,6 @@ export { default as MenuItem } from './Menu/MenuItem';
// @ts-ignore: has yet to be converted to TypeScript
export { default as SelectMenu, SELECT_MENU_DEFAULT_MESSAGE } from './Menu/SelectMenu';
// @ts-ignore: has yet to be converted to TypeScript
export { default as ModalCloseButton } from './Modal/ModalCloseButton';
// @ts-ignore: has yet to be converted to TypeScript
export { default as FullscreenModal, FULLSCREEN_MODAL_CLOSE_LABEL } from './Modal/FullscreenModal';
// @ts-ignore: has yet to be converted to TypeScript
export { default as MarketingModal } from './Modal/MarketingModal';
Expand Down