Adds open/close animations to dialogs and modals
This commit is contained in:
parent
fc066e05df
commit
b6cfe0933d
10 changed files with 635 additions and 224 deletions
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useRef, useState, ReactElement, ReactNode } from 'react';
|
||||
import React, { ReactElement, ReactNode, useRef, useState } from 'react';
|
||||
import Measure, { ContentRect, MeasuredComponentProps } from 'react-measure';
|
||||
import classNames from 'classnames';
|
||||
import { noop } from 'lodash';
|
||||
|
@ -10,6 +10,7 @@ import { LocalizerType } from '../types/Util';
|
|||
import { ModalHost } from './ModalHost';
|
||||
import { Theme } from '../util/theme';
|
||||
import { getClassNamesFor } from '../util/getClassNamesFor';
|
||||
import { useAnimated } from '../hooks/useAnimated';
|
||||
import { useHasWrapped } from '../hooks/useHasWrapped';
|
||||
|
||||
type PropsType = {
|
||||
|
@ -18,9 +19,12 @@ type PropsType = {
|
|||
hasXButton?: boolean;
|
||||
i18n: LocalizerType;
|
||||
moduleClassName?: string;
|
||||
noMouseClose?: boolean;
|
||||
onClose?: () => void;
|
||||
title?: ReactNode;
|
||||
};
|
||||
|
||||
type ModalPropsType = PropsType & {
|
||||
noMouseClose?: boolean;
|
||||
theme?: Theme;
|
||||
};
|
||||
|
||||
|
@ -36,8 +40,51 @@ export function Modal({
|
|||
onClose = noop,
|
||||
title,
|
||||
theme,
|
||||
}: Readonly<PropsType>): ReactElement {
|
||||
}: Readonly<ModalPropsType>): ReactElement {
|
||||
const { close, renderAnimation } = useAnimated(
|
||||
{
|
||||
from: { opacity: 0, transform: 'translateY(48px)' },
|
||||
enter: { opacity: 1, transform: 'translateY(0px)' },
|
||||
leave: {
|
||||
opacity: 0,
|
||||
transform: 'translateY(48px)',
|
||||
},
|
||||
config: {
|
||||
duration: 200,
|
||||
},
|
||||
},
|
||||
onClose
|
||||
);
|
||||
|
||||
return (
|
||||
<ModalHost noMouseClose={noMouseClose} onClose={close} theme={theme}>
|
||||
{renderAnimation(
|
||||
<ModalWindow
|
||||
hasStickyButtons={hasStickyButtons}
|
||||
hasXButton={hasXButton}
|
||||
i18n={i18n}
|
||||
moduleClassName={moduleClassName}
|
||||
onClose={close}
|
||||
title={title}
|
||||
>
|
||||
{children}
|
||||
</ModalWindow>
|
||||
)}
|
||||
</ModalHost>
|
||||
);
|
||||
}
|
||||
|
||||
export function ModalWindow({
|
||||
children,
|
||||
hasStickyButtons,
|
||||
hasXButton,
|
||||
i18n,
|
||||
moduleClassName,
|
||||
onClose = noop,
|
||||
title,
|
||||
}: Readonly<PropsType>): JSX.Element {
|
||||
const modalRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const bodyRef = useRef<HTMLDivElement | null>(null);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const [hasOverflow, setHasOverflow] = useState(false);
|
||||
|
@ -56,10 +103,10 @@ export function Modal({
|
|||
}
|
||||
|
||||
return (
|
||||
<ModalHost noMouseClose={noMouseClose} onClose={onClose} theme={theme}>
|
||||
<>
|
||||
{/* We don't want the click event to propagate to its container node. */}
|
||||
{/* eslint-disable jsx-a11y/no-static-element-interactions */}
|
||||
{/* eslint-disable jsx-a11y/click-events-have-key-events */}
|
||||
{/* eslint-disable-next-line max-len */}
|
||||
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}
|
||||
<div
|
||||
className={classNames(
|
||||
getClassName(''),
|
||||
|
@ -71,8 +118,6 @@ export function Modal({
|
|||
event.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{/* eslint-enable jsx-a11y/no-static-element-interactions */}
|
||||
{/* eslint-enable jsx-a11y/click-events-have-key-events */}
|
||||
{hasHeader && (
|
||||
<div className={getClassName('__header')}>
|
||||
{hasXButton && (
|
||||
|
@ -81,9 +126,7 @@ export function Modal({
|
|||
type="button"
|
||||
className={getClassName('__close-button')}
|
||||
tabIndex={0}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
onClick={onClose}
|
||||
/>
|
||||
)}
|
||||
{title && (
|
||||
|
@ -122,7 +165,7 @@ export function Modal({
|
|||
)}
|
||||
</Measure>
|
||||
</div>
|
||||
</ModalHost>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue