mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Added width and height attributes to the Modal component in AdminX (#18926)
no issues - the current combination of size and maxHeight attributes cover most of the use cases, but not all of them - this PR makes the size attribute have only named sizes (e.g. 'sm', 'md', 'full' etc.) - removes the maxHeight attirbute and adds new width and height attributes - width and height attributes can be any number (acts as max width and height in this situtaion) or 'full' - if size and width/height are both set, width/height should be priority
This commit is contained in:
parent
15d74b2840
commit
c490fb0940
9 changed files with 74 additions and 16 deletions
|
@ -41,9 +41,9 @@ export const ConfirmationModalContent: React.FC<ConfirmationModalProps> = ({
|
|||
formSheet={formSheet}
|
||||
okColor={okColor}
|
||||
okLabel={taskState === 'running' ? okRunningLabel : okLabel}
|
||||
size={540}
|
||||
testId='confirmation-modal'
|
||||
title={title}
|
||||
width={540}
|
||||
onCancel={onCancel}
|
||||
onOk={async () => {
|
||||
setTaskState('running');
|
||||
|
|
|
@ -23,9 +23,9 @@ export const LimitModalContent: React.FC<LimitModalProps> = ({
|
|||
formSheet={formSheet}
|
||||
okColor='green'
|
||||
okLabel={okLabel}
|
||||
size={540}
|
||||
testId='limit-modal'
|
||||
title={title}
|
||||
width={540}
|
||||
onOk={onOk}
|
||||
>
|
||||
<div className='py-4 leading-9'>
|
||||
|
|
|
@ -133,6 +133,44 @@ export const Bleed: Story = {
|
|||
}
|
||||
};
|
||||
|
||||
export const CustomWidth: Story = {
|
||||
args: {
|
||||
width: 600,
|
||||
onOk: () => {
|
||||
alert('Clicked OK!');
|
||||
},
|
||||
onCancel: undefined,
|
||||
title: 'Custom width modal',
|
||||
children: modalContent
|
||||
}
|
||||
};
|
||||
|
||||
export const CustomHeight: Story = {
|
||||
args: {
|
||||
size: 'md',
|
||||
height: 'full',
|
||||
onOk: () => {
|
||||
alert('Clicked OK!');
|
||||
},
|
||||
onCancel: undefined,
|
||||
title: 'Custom height modal',
|
||||
children: modalContent
|
||||
}
|
||||
};
|
||||
|
||||
export const Square: Story = {
|
||||
args: {
|
||||
width: 320,
|
||||
height: 320,
|
||||
onOk: () => {
|
||||
alert('Clicked OK!');
|
||||
},
|
||||
onCancel: undefined,
|
||||
title: 'Square modal',
|
||||
children: modalContent
|
||||
}
|
||||
};
|
||||
|
||||
export const CompletePage: Story = {
|
||||
args: {
|
||||
size: 'full',
|
||||
|
|
|
@ -8,7 +8,7 @@ import ButtonGroup from '../ButtonGroup';
|
|||
import Heading from '../Heading';
|
||||
import StickyFooter from '../StickyFooter';
|
||||
|
||||
export type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'bleed' | number;
|
||||
export type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'bleed';
|
||||
|
||||
export interface ModalProps {
|
||||
|
||||
|
@ -16,7 +16,8 @@ export interface ModalProps {
|
|||
* Possible values are: `sm`, `md`, `lg`, `xl, `full`, `bleed`. Yu can also use any number to set an arbitrary width.
|
||||
*/
|
||||
size?: ModalSize;
|
||||
maxHeight?: number;
|
||||
width?: 'full' | number;
|
||||
height?: 'full' | number;
|
||||
|
||||
testId?: string;
|
||||
title?: string;
|
||||
|
@ -50,7 +51,8 @@ export const topLevelBackdropClasses = 'bg-[rgba(98,109,121,0.2)] backdrop-blur-
|
|||
|
||||
const Modal: React.FC<ModalProps> = ({
|
||||
size = 'md',
|
||||
maxHeight,
|
||||
width,
|
||||
height,
|
||||
testId,
|
||||
title,
|
||||
okLabel = 'OK',
|
||||
|
@ -343,7 +345,7 @@ const Modal: React.FC<ModalProps> = ({
|
|||
|
||||
contentClasses = clsx(
|
||||
contentClasses,
|
||||
((size === 'full' || size === 'bleed') && 'grow')
|
||||
((size === 'full' || size === 'bleed' || height === 'full' || typeof height === 'number') && 'grow')
|
||||
);
|
||||
|
||||
const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
|
@ -352,14 +354,26 @@ const Modal: React.FC<ModalProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const modalStyles:{maxWidth?: string; maxHeight?: string;} = {};
|
||||
const modalStyles:{width?: string; height?: string; maxWidth?: string; maxHeight?: string;} = {};
|
||||
|
||||
if (typeof size === 'number') {
|
||||
modalStyles.maxWidth = size + 'px';
|
||||
if (typeof width === 'number') {
|
||||
modalStyles.width = '100%';
|
||||
modalStyles.maxWidth = width + 'px';
|
||||
} else if (width === 'full') {
|
||||
modalClasses = clsx(
|
||||
modalClasses,
|
||||
'w-full'
|
||||
);
|
||||
}
|
||||
|
||||
if (maxHeight) {
|
||||
modalStyles.maxHeight = maxHeight + 'px';
|
||||
if (typeof height === 'number') {
|
||||
modalStyles.height = '100%';
|
||||
modalStyles.maxHeight = height + 'px';
|
||||
} else if (height === 'full') {
|
||||
modalClasses = clsx(
|
||||
modalClasses,
|
||||
'h-full'
|
||||
);
|
||||
}
|
||||
|
||||
let footerContent;
|
||||
|
|
|
@ -18,6 +18,8 @@ export interface PreviewModalProps {
|
|||
title?: string;
|
||||
titleHeadingLevel?: HeadingLevel;
|
||||
size?: ModalSize;
|
||||
width?: 'full' | number;
|
||||
height?: 'full' | number;
|
||||
sidebar?: boolean | React.ReactNode;
|
||||
preview?: React.ReactNode;
|
||||
dirty?: boolean
|
||||
|
@ -54,6 +56,8 @@ export const PreviewModalContent: React.FC<PreviewModalProps> = ({
|
|||
title,
|
||||
titleHeadingLevel = 4,
|
||||
size = 'full',
|
||||
width,
|
||||
height,
|
||||
sidebar = '',
|
||||
preview,
|
||||
dirty = false,
|
||||
|
@ -244,10 +248,12 @@ export const PreviewModalContent: React.FC<PreviewModalProps> = ({
|
|||
afterClose={afterClose}
|
||||
animate={false}
|
||||
footer={false}
|
||||
height={height}
|
||||
padding={false}
|
||||
size={size}
|
||||
testId={testId}
|
||||
title=''
|
||||
width={width}
|
||||
hideXOnMobile
|
||||
>
|
||||
<div className='flex h-full grow'>
|
||||
|
|
|
@ -42,8 +42,8 @@ const AboutModal = NiceModal.create<RoutingModalProps>(({}) => {
|
|||
}}
|
||||
cancelLabel=''
|
||||
footer={(<></>)}
|
||||
size={540}
|
||||
topRightContent='close'
|
||||
width={540}
|
||||
>
|
||||
<div className='flex flex-col gap-4 pb-7 text-sm'>
|
||||
<GhostLogo className="h-auto w-[120px] dark:invert"/>
|
||||
|
|
|
@ -176,9 +176,9 @@ const InviteUserModal = NiceModal.create(() => {
|
|||
}}
|
||||
cancelLabel=''
|
||||
okLabel={okLabel}
|
||||
size={540}
|
||||
testId='invite-user-modal'
|
||||
title='Invite a new staff user'
|
||||
width={540}
|
||||
onOk={handleSendInvitation}
|
||||
>
|
||||
<div className='flex flex-col gap-6 py-4'>
|
||||
|
|
|
@ -89,12 +89,12 @@ const EmbedSignupFormModal = NiceModal.create(() => {
|
|||
}}
|
||||
cancelLabel=''
|
||||
footer={false}
|
||||
maxHeight={645}
|
||||
height={645}
|
||||
padding={false}
|
||||
size={1120}
|
||||
testId='embed-signup-form'
|
||||
title=''
|
||||
topRightContent='close'
|
||||
width={1120}
|
||||
>
|
||||
<div className='grid grid-cols-[5.2fr_2.8fr]'>
|
||||
<EmbedSignupPreview
|
||||
|
|
|
@ -284,9 +284,9 @@ const StripeConnectModal: React.FC = () => {
|
|||
}}
|
||||
cancelLabel=''
|
||||
footer={<div className='mt-8'></div>}
|
||||
size={stripeConnectAccountId ? 740 : 520}
|
||||
testId='stripe-modal'
|
||||
title=''
|
||||
width={stripeConnectAccountId ? 740 : 520}
|
||||
hideXOnMobile
|
||||
>
|
||||
{contents}
|
||||
|
|
Loading…
Add table
Reference in a new issue