You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.6 KiB
TypeScript
183 lines
5.6 KiB
TypeScript
import classNames from 'classnames';
|
|
import { ReactNode, useRef } from 'react';
|
|
import useKey from 'react-use/lib/useKey';
|
|
|
|
import styled from 'styled-components';
|
|
import { SessionIconButton } from './icon';
|
|
|
|
import { SessionFocusTrap } from './SessionFocusTrap';
|
|
import { Flex } from './basic/Flex';
|
|
import { SessionButton, SessionButtonColor, SessionButtonType } from './basic/SessionButton';
|
|
import { SpacerXL } from './basic/Text';
|
|
|
|
const StyledTitle = styled.div`
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
padding: 0 var(--margins-sm);
|
|
`;
|
|
|
|
export type SessionWrapperModalType = {
|
|
title?: string;
|
|
showHeader?: boolean;
|
|
onConfirm?: () => void;
|
|
onClose?: (event?: KeyboardEvent) => void;
|
|
showClose?: boolean;
|
|
confirmText?: string;
|
|
cancelText?: string;
|
|
showExitIcon?: boolean;
|
|
headerIconButtons?: Array<any>;
|
|
children: ReactNode;
|
|
headerReverse?: boolean;
|
|
additionalClassName?: string;
|
|
};
|
|
|
|
export const SessionWrapperModal = (props: SessionWrapperModalType) => {
|
|
const {
|
|
title,
|
|
onConfirm,
|
|
onClose,
|
|
showHeader = true,
|
|
showClose = false,
|
|
confirmText,
|
|
cancelText,
|
|
showExitIcon,
|
|
headerIconButtons,
|
|
headerReverse,
|
|
additionalClassName,
|
|
} = props;
|
|
|
|
useKey(
|
|
'Esc',
|
|
event => {
|
|
props.onClose?.(event);
|
|
},
|
|
undefined,
|
|
[props.onClose]
|
|
);
|
|
|
|
useKey(
|
|
'Escape',
|
|
event => {
|
|
props.onClose?.(event);
|
|
},
|
|
undefined,
|
|
[props.onClose]
|
|
);
|
|
|
|
const modalRef = useRef<HTMLDivElement>(null);
|
|
|
|
const handleClick = (e: any) => {
|
|
if (!modalRef.current?.contains(e.target)) {
|
|
props.onClose?.();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<SessionFocusTrap>
|
|
<div
|
|
className={classNames('loki-dialog modal', additionalClassName || null)}
|
|
onClick={handleClick}
|
|
role="dialog"
|
|
>
|
|
<div className="session-confirm-wrapper">
|
|
<div ref={modalRef} className="session-modal">
|
|
{showHeader ? (
|
|
<Flex
|
|
container={true}
|
|
flexDirection={headerReverse ? 'row-reverse' : 'row'}
|
|
justifyContent={'space-between'}
|
|
alignItems={'center'}
|
|
padding={'var(--margins-lg)'}
|
|
className={'session-modal__header'}
|
|
>
|
|
<Flex
|
|
container={true}
|
|
flexDirection={headerReverse ? 'row-reverse' : 'row'}
|
|
alignItems={'center'}
|
|
padding={'0'}
|
|
margin={'0'}
|
|
className={'session-modal__header__close'}
|
|
>
|
|
{showExitIcon ? (
|
|
<SessionIconButton
|
|
iconType="exit"
|
|
iconSize="small"
|
|
onClick={() => {
|
|
props.onClose?.();
|
|
}}
|
|
padding={'5px'}
|
|
margin={'0'}
|
|
dataTestId="modal-close-button"
|
|
/>
|
|
) : null}
|
|
{headerIconButtons?.length
|
|
? headerIconButtons.map((_, index) => {
|
|
const offset = showExitIcon
|
|
? headerIconButtons.length - 2
|
|
: headerIconButtons.length - 1;
|
|
if (index > offset) {
|
|
return null;
|
|
}
|
|
return <SpacerXL key={`session-modal__header_space-${index}`} />;
|
|
})
|
|
: null}
|
|
</Flex>
|
|
<StyledTitle className="session-modal__header__title">{title}</StyledTitle>
|
|
<Flex
|
|
container={true}
|
|
flexDirection={headerReverse ? 'row-reverse' : 'row'}
|
|
alignItems={'center'}
|
|
padding={'0'}
|
|
margin={'0'}
|
|
>
|
|
{headerIconButtons?.length ? (
|
|
headerIconButtons.map((iconItem: any) => {
|
|
return (
|
|
<SessionIconButton
|
|
key={iconItem.iconType}
|
|
iconType={iconItem.iconType}
|
|
iconSize={'large'}
|
|
iconRotation={iconItem.iconRotation}
|
|
onClick={iconItem.onClick}
|
|
padding={'0'}
|
|
margin={'0'}
|
|
/>
|
|
);
|
|
})
|
|
) : showExitIcon ? (
|
|
<SpacerXL />
|
|
) : null}
|
|
</Flex>
|
|
</Flex>
|
|
) : null}
|
|
|
|
<div className="session-modal__body">
|
|
<div className="session-modal__centered">
|
|
{props.children}
|
|
|
|
<div className="session-modal__button-group">
|
|
{onConfirm ? (
|
|
<SessionButton buttonType={SessionButtonType.Simple} onClick={props.onConfirm}>
|
|
{confirmText || window.i18n('okay')}
|
|
</SessionButton>
|
|
) : null}
|
|
{onClose && showClose ? (
|
|
<SessionButton
|
|
buttonType={SessionButtonType.Simple}
|
|
buttonColor={SessionButtonColor.Danger}
|
|
onClick={props.onClose}
|
|
>
|
|
{cancelText || window.i18n('close')}
|
|
</SessionButton>
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</SessionFocusTrap>
|
|
);
|
|
};
|