mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
Added global confirmation modal to AdminX
refs. https://github.com/TryGhost/Team/issues/3351
This commit is contained in:
parent
50618921c6
commit
0fd415c1d7
@ -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'
|
||||
}
|
||||
};
|
@ -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);
|
@ -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;
|
@ -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;
|
||||
}
|
||||
|
@ -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>}
|
||||
|
Loading…
Reference in New Issue
Block a user