Modal

import { Modal } from '@megafon/ui-core';
Примеры и код
Свойства и методы
Код DemoModalWrapper
export const DemoModalWrapper: React.FC<IDemoModalWrapperProps> = ({ children }) => {
const [isOpened, setIsOpened] = React.useState<boolean>(false);
const [isShowBackButton, setIsShowBackButton] = React.useState<boolean>(false);
const [isChangeMobileView, setIsChangeMobileView] = React.useState<boolean>(false);
const [isChangeProps, setIsChangeProps] = React.useState<boolean>(false);
const handleOpen = (): void => {
setIsOpened(true);
};
const handleCLose = (): void => {
setIsOpened(false);
setIsShowBackButton(false);
setIsChangeMobileView(false);
setIsChangeProps(false);
};
const handleChangeShowBackButton =
(value: boolean): (() => void) =>
(): void => {
setIsShowBackButton(value);
};
const handleChangeMobileView = (): void => {
setIsChangeMobileView(true);
};
const handleChangeProps = (): void => {
setIsChangeProps(true);
};
const renderStaticFooter: JSX.Element = (
<div style={{ paddingTop: '24px', textAlign: 'center' }}>
<Button onClick={handleCLose}>Закрыть</Button>
</div>
);
const renderStickyFooter: JSX.Element = (
<div style={{ padding: '32px 0', textAlign: 'center' }}>
<Button onClick={handleCLose}>Закрыть</Button>
</div>
);
const renderActiveButtonFooter: JSX.Element = (
<div style={{ display: 'flex', justifyContent: 'center', padding: '32px 0', textAlign: 'center' }}>
{!isShowBackButton && (
<div style={{ marginRight: '16px' }}>
<Button onClick={handleChangeShowBackButton(true)}>Далее</Button>
</div>
)}
<Button type="outline" onClick={handleCLose}>
Закрыть
</Button>
</div>
);
const renderChangeMobileViewButtonFooter: JSX.Element = (
<div style={{ display: 'flex', justifyContent: 'center', paddingTop: '24px', textAlign: 'center' }}>
{!isChangeMobileView && (
<div style={{ marginRight: '16px' }}>
<Button onClick={handleChangeMobileView}>Далее</Button>
</div>
)}
<Button type="outline" onClick={handleCLose}>
Закрыть
</Button>
</div>
);
const renderChangePropsButtonFooter: JSX.Element = (
<div style={{ display: 'flex', justifyContent: 'center', paddingTop: '24px', textAlign: 'center' }}>
<div style={{ marginRight: '16px' }}>
<Button onClick={handleChangeProps}>Далее</Button>
</div>
<Button type="outline" onClick={handleCLose}>
Закрыть
</Button>
</div>
);
return (
<div>
{children({
isOpened,
isShowBackButton,
isChangeMobileView,
isChangeProps,
staticFooter: renderStaticFooter,
stickyFooter: renderStickyFooter,
activeButtonFooter: renderActiveButtonFooter,
changeMobileViewButtonFooter: renderChangeMobileViewButtonFooter,
changePropsButtonFooter: renderChangePropsButtonFooter,
onClose: handleCLose,
onOpen: handleOpen,
onChangeShowBackButton: handleChangeShowBackButton,
})}
</div>
);
};

Базовое использование

Без заголовка

<DemoModalWrapper>
  {({ isOpened, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal isOpened={isOpened} onClose={onClose}>
              <DemoModalContentMedium />
          </Modal>
      </>
  }
</DemoModalWrapper>

С заголовком

<DemoModalWrapper>
  {({ isOpened, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal headerProps={{ headerTitle: 'Услуги связи' }} isOpened={isOpened} onClose={onClose}>
              <DemoModalContentMedium />
          </Modal>
      </>
  }
</DemoModalWrapper>

С длинным контентом

<DemoModalWrapper>
  {({ isOpened, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal headerProps={{ headerTitle: 'Услуги связи' }} isOpened={isOpened} onClose={onClose}>
              <DemoModalContentLong />
          </Modal>
      </>
  }
</DemoModalWrapper>

Настройки шапки

С кнопкой назад и дополнительным контентом

<DemoModalWrapper>
  {({ isOpened, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{
                  headerTitle: 'Услуги связи',
                  showBackButton: true,
                  headerAdditionalContent: 'Дополнительный контент в шапке попапа',
              }}
              isOpened={isOpened}
              onClose={onClose}
          >
              <DemoModalContentMedium />
          </Modal>
      </>
  }
</DemoModalWrapper>

С незафиксированной шапкой

<DemoModalWrapper>
  {({ isOpened, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{ headerTitle: 'Услуги связи', isStickyHeader: false }}
              isOpened={isOpened}
              onClose={onClose}
          >
              <DemoModalContentLong />
          </Modal>
      </>
  }
</DemoModalWrapper>

Настройки футера

Отображение футера

<DemoModalWrapper>
  {({ isOpened, staticFooter, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{ headerTitle: 'Услуги связи' }}
              footerProps={{ footer: staticFooter }}
              isOpened={isOpened}
              onClose={onClose}
          >
              <DemoModalContentMedium />
          </Modal>
      </>
  }
</DemoModalWrapper>

Зафиксированный футер с тенью

<DemoModalWrapper>
  {({ isOpened, stickyFooter, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{ headerTitle: 'Услуги связи' }}
              footerProps={{
                  footer: stickyFooter,
                  isStickyFooter: true,
                  hasFooterShadow: true,
              }}
              isOpened={isOpened}
              onClose={onClose}
          >
              <DemoModalContentLong />
          </Modal>
      </>
  }
</DemoModalWrapper>

Другие настройки

Вид шторки на мобилках

<DemoModalWrapper>
  {({ isOpened, staticFooter, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{ headerTitle: 'Услуги связи' }}
              footerProps={{ footer: staticFooter }}
              mobileView={MODAL_MOBILE_VIEWS_ENUM.BOTTOM}
              isOpened={isOpened}
              onClose={onClose}
          >
              <DemoModalContentShort />
          </Modal>
      </>
  }
</DemoModalWrapper>

Без кастомного скролла с кнопками вне основной шапки и подложкой

<DemoModalWrapper>
  {({ isOpened, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{ isOutSideHeaderButtons: true, hasHeaderButtonsShadow: true }}
              isEnabledNativeScroll
              isOpened={isOpened}
              onClose={onClose}
          >
              <p style={{ padding: '60px 40px 40px' }}>
                  <DemoModalContentLong />
              </p>
          </Modal>
      </>
  }
</DemoModalWrapper>

Динамическое изменение высоты попапа при изменении контента внутри

<DemoModalWrapper>
  {({ isOpened, isShowBackButton, activeButtonFooter, onClose, onOpen, onChangeShowBackButton }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{
                  headerTitle: 'Услуги связи',
                  showBackButton: isShowBackButton,
                  onBackButtonClick: onChangeShowBackButton(false),
              }}
              footerProps={{
                  footer: activeButtonFooter,
                  isStickyFooter: true,
              }}
              isOpened={isOpened}
              onClose={onClose}
          >
              {isShowBackButton ? <DemoModalContentLong /> : <DemoModalContentMedium />}
          </Modal>
      </>
  }
</DemoModalWrapper>

Пересчет максимальной высоты скролла при изменении вида на мобилках

<DemoModalWrapper>
  {({ isOpened, isChangeMobileView, changeMobileViewButtonFooter, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{
                  headerTitle: 'Услуги связи',
              }}
              footerProps={{
                  footer: changeMobileViewButtonFooter,
              }}
              mobileView={isChangeMobileView ? MODAL_MOBILE_VIEWS_ENUM.FULL_SCREEN : MODAL_MOBILE_VIEWS_ENUM.BOTTOM}
              isOpened={isOpened}
              onClose={onClose}
          >
              {<DemoModalContentShort />}
          </Modal>
      </>
  }
</DemoModalWrapper>

Пересчет максимальной высоты скролла при изменении шапки и футера

<DemoModalWrapper>
  {({ isOpened, isChangeProps, staticFooter, changePropsButtonFooter, onClose, onOpen }) =>
      <>
          <span>
              <Button onClick={onOpen}>Open</Button>
          </span>
          <Modal
              headerProps={{
                  headerTitle: 'Услуги связи',
                  headerAdditionalContent: isChangeProps ? 'Дополнительный контент в шапке' : '',
              }}
              footerProps={{
                  footer: isChangeProps ? staticFooter : changePropsButtonFooter
              }}
              isRecalculateHeight
              isOpened={isOpened}
              onClose={onClose}
          >
              {<DemoModalContentShort />}
          </Modal>
      </>
  }
</DemoModalWrapper>
Prop nameTypeDefaultDescription
classNamestringДополнительные классы для корневого элемента
classesModalClassesTypeДополнительные классы для внутренних элементов
dataAttrsModalDataAttrsTypeДополнительные data-атрибуты к внутренним элементам
isOpened*booleanСостояние открытости
scrollBarParamsOmit<IScrollBarProps, "maxHeight">Настройки для кастомного компонента скролла
headerPropsModalHeaderPropsTypeНастройки для шапки модального окна
footerPropsModalFooterPropsTypeНастройки для футера модального окна
mobileViewMODAL_MOBILE_VIEWS_ENUMMODAL_MOBILE_VIEWS_ENUM.FULL_SCREENВид модального окна на разрешении 767-
isEnabledNativeScrollbooleanВключить дефолтный скролл (отключает кастомный компонент скролла)
isSwipeDisabledbooleanОтключить закрытие шторки свайпом
isDisabledBackgroundClickbooleanОтключить закрытие модального окна при клике на фон
isReturnFocusAfterClosebooleantrueВосстанавливает фокус на элементе, который был сфокусирован до открытия модального окна
isRecalculateHeightbooleanПересчитывать максимальную высоту скролла
hideAriaAppbooleanfalseДолжен ли root-элемент приложения быть скрыт
contentLabelstringУстанавливает aria-label
onClose() => voidОбработчик закрытия модального окна
onAfterModalOpen() => voidОбработчик после открытия модального окна
getModalContentRef(node: HTMLDivElement) => voidRef обработчик для Content
getModalOverlayRef(node: HTMLDivElement) => voidRef обработчик для Overlay
export type ModalClassesType = {
bodyOpen?: string;
modalContent?: string;
overlay?: string;
background?: string;
containerWrap?: string;
containerInner?: string;
containerBody?: string;
header?: string;
headerBackButton?: string;
headerCloseButton?: string;
titleArea?: string;
title?: string;
children?: string;
childrenContent?: string;
footer?: string;
};
export type ModalDataAttrsType = {
background?: Record<string, string>;
headerBackButton?: Record<string, string>;
headerCloseButton?: Record<string, string>;
containerWrap?: Record<string, string>;
containerInner?: Record<string, string>;
containerBody?: Record<string, string>;
};
export type ModalHeaderPropsType = {
/** Заголовок */
headerTitle?: string | JSX.Element | null;
/** Отобразить стрелку назад */
showBackButton?: boolean;
/** Скрыть крестик */
hideCloseButton?: boolean;
/** Отобразить дополнительный контент в шапке */
headerAdditionalContent?: JSX.Element | JSX.Element[] | string | null;
/** Отобразить тень у шапки */
hasHeaderShadow?: boolean;
/** Отобразить кнопки с подложкой */
hasHeaderButtonsShadow?: boolean;
/** Закрепленная шапка */
isStickyHeader?: boolean;
/** Кнопки находятся вне основной шапке */
isOutSideHeaderButtons?: boolean;
/** Обработчик для стрелки назад */
onBackButtonClick?: () => void;
};
export type ModalFooterPropsType = {
/** Футер */
footer?: JSX.Element | JSX.Element[] | string | null;
/** Закрепить футер */
isStickyFooter?: boolean;
/** Отобразить тень у футера */
hasFooterShadow?: boolean;
};