diff --git a/packages/docs/src/locales/en/en.json b/packages/docs/src/locales/en/en.json index 6d23fc2e96..6eb6c6f5b0 100644 --- a/packages/docs/src/locales/en/en.json +++ b/packages/docs/src/locales/en/en.json @@ -332,6 +332,7 @@ "overlayOpacity": "Set the overlay's opacity", "anchorClass": "Set class name to the `anchor` slot container", "zIndex": "Set the modal's `z-index`", + "fixBody": "Set `body` position to `fixed` to prevent document scroll while modal is open.", "blur": "Use `blur` filter to overlay. Root `css` variable `--va-modal-overlay-background-blur-radius` sets the blur radius" }, "events": { diff --git a/packages/docs/src/locales/ru/ru.json b/packages/docs/src/locales/ru/ru.json index 2cadaa3a8a..c78f0f0c8e 100644 --- a/packages/docs/src/locales/ru/ru.json +++ b/packages/docs/src/locales/ru/ru.json @@ -331,6 +331,7 @@ "overlayOpacity": "Прозрачность оверлея", "anchorClass": "Назначение имени класса для контейнера слота `anchor`", "zIndex": " CSS свойство `z-index`", + "fixBody": "Запрещает прокрутку документа при открытом модальном окне.", "blur": "Устанавливает `blur` фильтр оверлея. Рутовая `css` переменная `--va-modal-overlay-background-blur-radius` устанавливает радиус `blur` фильтра" }, "events": { diff --git a/packages/ui/src/components/va-modal/VaModal.vue b/packages/ui/src/components/va-modal/VaModal.vue index 448be5bc0b..9e0ff877e8 100644 --- a/packages/ui/src/components/va-modal/VaModal.vue +++ b/packages/ui/src/components/va-modal/VaModal.vue @@ -139,6 +139,7 @@ import { useModalLevel, useTranslation, useClickOutside, + useDocument, } from '../../composables' import { VaButton } from '../va-button' @@ -170,6 +171,7 @@ export default defineComponent({ ...useStatefulProps, modelValue: { type: Boolean, default: false }, attachElement: { type: String, default: 'body' }, + fixBody: { type: Boolean, default: false }, disableAttachment: { type: Boolean, default: false }, title: { type: String, default: '' }, message: { type: String, default: '' }, @@ -295,14 +297,25 @@ export default defineComponent({ useBlur(toRef(props, 'blur'), valueComputed) + const documentRef = useDocument() + const setBodyPosition = (position: string) => { + if (!documentRef.value || !props.fixBody) { return } + + documentRef.value.body.style.position = position + } + const setFixedBodyPosition = () => setBodyPosition('fixed') + const resetBodyPosition = () => setBodyPosition('') + watch(valueComputed, newValueComputed => { // watch for open/close modal if (newValueComputed) { registerModal() + setFixedBodyPosition() return } if (isLowestLevelModal.value) { freeFocus() + resetBodyPosition() } unregisterModal() })