Fix <Modal> footers with long-text or lots of buttons

This commit is contained in:
Evan Hahn 2021-05-27 11:43:39 -04:00 committed by GitHub
parent 6664315e3a
commit 7038a3f3ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 48 additions and 20 deletions

View file

@ -91,13 +91,15 @@
padding: 16px;
}
&__footer {
&__button-footer {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
margin-top: 16px;
margin-top: 8px;
.module-Button {
margin-left: 8px;
margin-top: 8px;
}
}

View file

@ -22,8 +22,8 @@ export const Alert: FunctionComponent<PropsType> = ({
}) => (
<Modal i18n={i18n} onClose={onClose} title={title}>
{body}
<Modal.Footer>
<Modal.ButtonFooter>
<Button onClick={onClose}>{i18n('Confirmation--confirm')}</Button>
</Modal.Footer>
</Modal.ButtonFooter>
</Modal>
);

View file

@ -118,7 +118,7 @@ export const CallingSelectPresentingSourcesModal = ({
/>
))}
</div>
<Modal.Footer moduleClassName="module-CallingSelectPresentingSourcesModal">
<Modal.ButtonFooter moduleClassName="module-CallingSelectPresentingSourcesModal">
<Button
onClick={() => setPresenting()}
variant={ButtonVariant.Secondary}
@ -131,7 +131,7 @@ export const CallingSelectPresentingSourcesModal = ({
>
{i18n('calling__SelectPresentingSourcesModal--confirm')}
</Button>
</Modal.Footer>
</Modal.ButtonFooter>
</Modal>
);
};

View file

@ -43,14 +43,14 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
<section>
<p>{i18n('CaptchaDialog--can-close__body')}</p>
</section>
<Modal.Footer>
<Modal.ButtonFooter>
<Button onClick={onCancelClick} variant={ButtonVariant.Secondary}>
{i18n('cancel')}
</Button>
<Button onClick={onSkipClick} variant={ButtonVariant.Destructive}>
{i18n('CaptchaDialog--can_close__skip-verification')}
</Button>
</Modal.Footer>
</Modal.ButtonFooter>
</Modal>
);
}
@ -80,7 +80,7 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
<p>{i18n('CaptchaDialog__first-paragraph')}</p>
<p>{i18n('CaptchaDialog__second-paragraph')}</p>
</section>
<Modal.Footer>
<Modal.ButtonFooter>
<Button
disabled={isPending}
onClick={onContinueClick}
@ -93,7 +93,7 @@ export function CaptchaDialog(props: Readonly<PropsType>): JSX.Element {
'Continue'
)}
</Button>
</Modal.Footer>
</Modal.ButtonFooter>
</Modal>
);
}

View file

@ -78,7 +78,7 @@ export const ConfirmationDialog = React.memo(
return (
<Modal i18n={i18n} onClose={cancelAndClose} title={title} theme={theme}>
{children}
<Modal.Footer>
<Modal.ButtonFooter>
<Button
onClick={handleCancel}
ref={focusRef}
@ -101,7 +101,7 @@ export const ConfirmationDialog = React.memo(
{action.text}
</Button>
))}
</Modal.Footer>
</Modal.ButtonFooter>
</Modal>
);
}

View file

@ -35,7 +35,7 @@ export const ErrorModal = (props: PropsType): JSX.Element => {
<div className="module-error-modal__description">
{description || i18n('ErrorModal--description')}
</div>
<Modal.Footer>
<Modal.ButtonFooter>
<Button
onClick={onClose}
ref={focusRef}
@ -43,7 +43,7 @@ export const ErrorModal = (props: PropsType): JSX.Element => {
>
{buttonText || i18n('Confirmation--confirm')}
</Button>
</Modal.Footer>
</Modal.ButtonFooter>
</>
</Modal>
);

View file

@ -2,12 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { noop } from 'lodash';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
import { Button } from './Button';
import { Modal } from './Modal';
const i18n = setupI18n('en', enMessages);
@ -30,10 +32,31 @@ story.add('Bare bones, long', () => (
</Modal>
));
story.add('Title, X button, body, and footer', () => (
story.add('Title, X button, body, and button footer', () => (
<Modal i18n={i18n} title="Hello world" onClose={onClose} hasXButton>
{LOREM_IPSUM}
<Modal.Footer>Footer</Modal.Footer>
<Modal.ButtonFooter>
<Button onClick={noop}>Okay</Button>
</Modal.ButtonFooter>
</Modal>
));
story.add('Lots of buttons in the footer', () => (
<Modal i18n={i18n} onClose={onClose}>
Hello world!
<Modal.ButtonFooter>
<Button onClick={noop}>Okay</Button>
<Button onClick={noop}>Okay</Button>
<Button onClick={noop}>Okay</Button>
<Button onClick={noop}>
This is a button with a fairly large amount of text
</Button>
<Button onClick={noop}>Okay</Button>
<Button onClick={noop}>
This is a button with a fairly large amount of text
</Button>
<Button onClick={noop}>Okay</Button>
</Modal.ButtonFooter>
</Modal>
));

View file

@ -85,7 +85,7 @@ export function Modal({
);
}
Modal.Footer = ({
Modal.ButtonFooter = ({
children,
moduleClassName,
}: Readonly<{
@ -93,7 +93,10 @@ Modal.Footer = ({
moduleClassName?: string;
}>): ReactElement => (
<div
className={getClassNamesFor(BASE_CLASS_NAME, moduleClassName)('__footer')}
className={getClassNamesFor(
BASE_CLASS_NAME,
moduleClassName
)('__button-footer')}
>
{children}
</div>

View file

@ -37,7 +37,7 @@ export const NeedsScreenRecordingPermissionsModal = ({
<li>{i18n('calling__presenting--permission-instruction-step3')}</li>
<li>{i18n('calling__presenting--permission-instruction-step4')}</li>
</ol>
<Modal.Footer>
<Modal.ButtonFooter>
<Button
onClick={toggleScreenRecordingPermissionsDialog}
ref={focusRef}
@ -54,7 +54,7 @@ export const NeedsScreenRecordingPermissionsModal = ({
>
{i18n('calling__presenting--permission-open')}
</Button>
</Modal.Footer>
</Modal.ButtonFooter>
</Modal>
);
};