Added global confirmation modal to AdminX

refs. https://github.com/TryGhost/Team/issues/3351
This commit is contained in:
Peter Zimon 2023-06-02 12:01:16 +02:00
parent 50618921c6
commit 0fd415c1d7
5 changed files with 114 additions and 4 deletions

View File

@ -0,0 +1,36 @@
import type {Meta, StoryObj} from '@storybook/react';
import ConfirmationModal from './ConfirmationModal';
import ConfirmationModalContainer from './ConfirmationModalContainer';
import NiceModal from '@ebay/nice-modal-react';
const meta = {
title: 'Global / Modal / Confirmation Modal',
component: ConfirmationModal,
tags: ['autodocs'],
decorators: [(_story: any, context: any) => (
<NiceModal.Provider>
<ConfirmationModalContainer {...context.args} />
</NiceModal.Provider>
)]
} satisfies Meta<typeof ConfirmationModal>;
export default meta;
type Story = StoryObj<typeof ConfirmationModal>;
export const Default: Story = {
args: {
title: 'Are you sure?',
prompt: 'Watch out, you\'re doing something super-super dangerous. Don\'t press the red button (you know you will).'
}
};
export const CustomButtons: Story = {
args: {
...Default.args,
title: 'You want to delete?',
cancelLabel: 'Meh',
okLabel: 'Alrite',
okColor: 'red'
}
};

View File

@ -0,0 +1,45 @@
import Modal from './Modal';
import NiceModal from '@ebay/nice-modal-react';
import React from 'react';
export interface ConfirmationModalProps {
title?: string;
prompt?: React.ReactNode;
cancelLabel?: string;
okLabel?: string;
okColor?: string;
onCancel?: () => void;
onOk?: () => void;
customFooter?: React.ReactNode;
}
const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
title = 'Are you sure?',
prompt,
cancelLabel = 'Cancel',
okLabel = 'OK',
okColor = 'black',
onCancel,
onOk,
customFooter
}) => {
return (
<Modal
backDrop={false}
cancelLabel={cancelLabel}
customFooter={customFooter}
okColor={okColor}
okLabel={okLabel}
size={540}
title={title}
onCancel={onCancel}
onOk={onOk}
>
<div className='py-4'>
{prompt}
</div>
</Modal>
);
};
export default NiceModal.create(ConfirmationModal);

View File

@ -0,0 +1,14 @@
import Button from './Button';
import ConfirmationModal, {ConfirmationModalProps} from './ConfirmationModal';
import NiceModal from '@ebay/nice-modal-react';
import React from 'react';
const ConfirmationModalContainer: React.FC<ConfirmationModalProps> = ({...props}) => {
return (
<Button color='black' label='Open confirmation modal' onClick={() => {
NiceModal.show(ConfirmationModal, {...props});
}} />
);
};
export default ConfirmationModalContainer;

View File

@ -21,7 +21,16 @@ interface IHeading {
className?: string;
}
const Heading: React.FC<IHeading> = ({level, children, styles, grey, separator, useLabelTag, className, ...props}) => {
const Heading: React.FC<IHeading> = ({
level,
children,
styles = '',
grey,
separator,
useLabelTag,
className = '',
...props
}) => {
if (!level) {
level = 1;
}

View File

@ -23,6 +23,7 @@ export interface ModalProps {
onOk?: () => void;
onCancel?: () => void;
children?: React.ReactNode;
backDrop?: boolean;
}
const Modal: React.FC<ModalProps> = ({
@ -36,7 +37,8 @@ const Modal: React.FC<ModalProps> = ({
onOk,
okColor = 'black',
onCancel,
children
children,
backDrop = true
}) => {
const modal = useModal();
@ -99,8 +101,12 @@ const Modal: React.FC<ModalProps> = ({
break;
}
if (!backDrop) {
modalClasses += ' border border-grey-100 ';
}
const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {
if (e.target === e.currentTarget) {
if (e.target === e.currentTarget && backDrop) {
modal.remove();
}
};
@ -111,7 +117,7 @@ const Modal: React.FC<ModalProps> = ({
return (
<div className={backdropClasses} id='modal-backdrop' onClick={handleBackdropClick}>
<div className='pointer-events-none fixed inset-0 z-0 bg-[rgba(98,109,121,0.15)] backdrop-blur-[3px]'></div>
<div className={`pointer-events-none fixed inset-0 z-0 ${backDrop && 'bg-[rgba(98,109,121,0.15)] backdrop-blur-[3px]'}`}></div>
<section className={modalClasses} style={modalStyles}>
<div className='h-full'>
{title && <Heading level={4}>{title}</Heading>}