signal-desktop/ts/components/ConfirmationDialog.tsx

111 lines
3.1 KiB
TypeScript
Raw Normal View History

2020-10-30 20:34:04 +00:00
// Copyright 2019-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import classNames from 'classnames';
import { LocalizerType } from '../types/Util';
2020-05-27 21:37:06 +00:00
export type ActionSpec = {
text: string;
action: () => unknown;
style?: 'affirmative' | 'negative';
};
export type OwnProps = {
readonly i18n: LocalizerType;
readonly children: React.ReactNode;
2020-05-27 21:37:06 +00:00
readonly title?: string | React.ReactNode;
readonly actions: Array<ActionSpec>;
readonly onClose: () => unknown;
};
export type Props = OwnProps;
function focusRef(el: HTMLElement | null) {
if (el) {
el.focus();
}
}
export const ConfirmationDialog = React.memo(
2020-05-27 21:37:06 +00:00
({ i18n, onClose, children, title, actions }: Props) => {
2020-01-08 17:44:54 +00:00
React.useEffect(() => {
const handler = ({ key }: KeyboardEvent) => {
if (key === 'Escape') {
onClose();
}
};
document.addEventListener('keydown', handler);
2020-01-08 17:44:54 +00:00
return () => {
document.removeEventListener('keydown', handler);
};
}, [onClose]);
const handleCancel = React.useCallback(
(e: React.MouseEvent) => {
if (e.target === e.currentTarget) {
onClose();
}
},
[onClose]
);
2020-05-27 21:37:06 +00:00
const handleAction = React.useCallback(
(e: React.MouseEvent<HTMLButtonElement>) => {
onClose();
if (e.currentTarget.dataset.action) {
const actionIndex = parseInt(e.currentTarget.dataset.action, 10);
const { action } = actions[actionIndex];
action();
}
},
[onClose, actions]
);
return (
<div className="module-confirmation-dialog__container">
2020-05-27 21:37:06 +00:00
{title ? (
<h1 className="module-confirmation-dialog__container__title">
{title}
</h1>
) : null}
<div className="module-confirmation-dialog__container__content">
{children}
</div>
{actions.length > 0 && (
<div className="module-confirmation-dialog__container__buttons">
<button
2020-09-12 00:46:52 +00:00
type="button"
onClick={handleCancel}
ref={focusRef}
className="module-confirmation-dialog__container__buttons__button"
>
{i18n('confirmation-dialog--Cancel')}
</button>
{actions.map((action, i) => (
<button
2020-09-12 00:46:52 +00:00
type="button"
key={action.text}
onClick={handleAction}
data-action={i}
className={classNames(
'module-confirmation-dialog__container__buttons__button',
action.style === 'affirmative'
? 'module-confirmation-dialog__container__buttons__button--affirmative'
: null,
action.style === 'negative'
? 'module-confirmation-dialog__container__buttons__button--negative'
: null
)}
>
{action.text}
</button>
))}
</div>
)}
</div>
);
}
);