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>
 | 
						|
  );
 | 
						|
};
 |