UNPKG

@yandex/ui

Version:

Yandex UI components

114 lines (88 loc) 9.62 kB
# Modal <a href='https://github.yandex-team.ru/search-interfaces/frontend/tree/master/packages/lego-components/src/Modal' target='_blank'><img src='https://badger.yandex-team.ru/custom/[Исходники]/[Github ][green]/badge.svg' /></a> <a href='https://search.yandex-team.ru/stsearch?text=Modal.ts&facet.queue=ISL&facet.type=bug&facet.status=128' target='_blank'><img src='https://badger.yandex-team.ru/custom/[Известные проблемы]/[Startrek][blue]/badge.svg' /></a> <!-- description:start --> Используется для создания всплывающих модальных окон. <!-- description:end --> ## Пример использования Использование с нужным набором модификаторов: ```ts import React from 'react' import { compose } from '@bem-react/core' import { Modal as ModalDesktop, withThemeNormal, } from '@yandex-lego/components/Modal/desktop' import { withZIndex } from '@yandex-lego/components/withZIndex' // Композиция из различных модификаторов const Modal = compose( withThemeNormal, withZIndex, )(ModalDesktop) const App = () => ( <Modal theme="normal" onClose={() => this.setState({ visible: false })} visible={this.state.visible} zIndexGroupLevel={20} > Привет! </Modal> ) ``` Использование с полным набором модификаторов: ```ts // src/App.ts import React from 'react' import { Modal } from '@yandex-lego/components/Modal/desktop/bundle' const App = () => ( <Modal theme="normal" onClose={() => this.setState({ visible: false })} visible={this.state.visible} zIndexGroupLevel={20} > Привет! </Modal> ) ``` ## Примеры ### Базовое использование Чтобы закрыть модальное окно, установите обработчик `onClose`, в котором измените состояние видимости. Данный обработчик вызывается при нажатии на клавишу `esc`, либо при клике за пределами содержимого модального окна. {{%story::desktop:surface-modal-desktop--playground%}} ### Стилевое оформление Чтобы изменить стилевое оформление модального окна, установите свойство `theme` в значение `"normal"`. На уровне `desktop` отвечает за анимацию его открытия/закрытия. ## Свойства <!-- props:start --> | Свойство | Тип | По умолчанию | Описание | | --------------------- | ------------------------------------------------------------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | contentVerticalAlign? | `"top" \| "middle" \| "bottom"` | `'middle'` | Выравнивание контента по вертикали | | hasAnimation? | `false \| true` | `true` | Добавляет анимацию при открытии модального окна | | keepMounted? | `false \| true` | `true` | Сохраняет контейнер в DOM после создания | | className? | `string` | — | Дополнительный класс | | innerRef? | `(instance: HTMLDivElement) => void \| RefObject<HTMLDivElement>` | — | Ссылка на корневой DOM-элемент компонента | | zIndex? | `number` | — | Задает слой `z-index` | | visible? | `false \| true` | — | Делает попап видимым | | scope? | `RefObject<HTMLElement>` | `document.body` | Ссылка на DOM-элемент, в котором размещается попап<br>Важно, чтобы контейнер имел `position: relative` для корректного позиционирования | | forceRender? | `false \| true` | — | Вызывает дополнительный рендер после создания | | onClose? | `(event: KeyboardEvent \| MouseEvent, source: "esc" \| "click") => void` | — | Обработчик, вызываемый после нажатия на клавишу Esc либо мышкой на область вне контейнера | | onClick? | `(event: MouseEvent<HTMLDivElement, MouseEvent>) => void` | — | Обработчик, вызываемый при срабатывании события click | <!-- props:end --> ## Примечание - Функциональность модального окна основана на компоненте `Popup`. - Позиционирование компонента выполняется только с помощью CSS. - Анимация открытия реализована только на уровне `desktop`. - В модальном окне нет зацикливания фокуса. ### Скрытие ползунков страницы при открытии модального окна У компонента `Modal` отсутствует встроенный механизм скрытия ползунков на странице. ### Проблема с пролистыванием страницы на iOS и Android Для позиционирования модального окна поверх контента страницы в компоненте `Modal` используется CSS-стиль `position: fixed`. Его использование в браузерах на iOS и Android устройствах приводит к тому, что при прокрутке содержимого модального окна прокручивается и страница под ним. Это происходит из-за того, что на iOS и Android нельзя убрать прокрутку `<body>`. Даже если применить `overflow: hidden`, страница все равно будет прокручиваться. Варианты решения: 1. При открытии модального окна замените `position:fixed; height: <window height>; overflow:hidden` на `<body>`. **Недостаток:** текущее положение на странице собьется, поэтому его нужно будет запоминать и выставлять заново. При этом страница под модальным окном будет «скакать»: при его открытии она прокрутится в самое верхнее положение, а при закрытии - вернется в предыдущее. 2. Позиционируйте модальное окно с помощью `position: absolute` и сделайте так, чтобы контент модального окна прокручивался вместе со страницей. **Недостаток:** можно прокрутить модальное окно далеко вниз или вверх и «потерять» его. 3. Предотвратите события `touchmove`, которые вызывают прокрутку не контента попапа, а самой страницы. **Недостаток:** невозможно отличить события, которые вызывают прокрутку модального окна от событий, которые вызывают прокрутку страницы, т.к. технически они одинаковы.