feat: prevent scrolling the rest of the page when a modal is open

This commit is contained in:
kolaente 2022-02-27 16:08:46 +01:00 committed by Gitea
parent 3639498b3f
commit 574ecff12d

View file

@ -60,57 +60,50 @@
</transition> </transition>
</template> </template>
<script> <script lang="ts" setup>
import BaseButton from '@/components/base/BaseButton.vue' import BaseButton from '@/components/base/BaseButton.vue'
import {onUnmounted, watch} from 'vue'
export const TRANSITION_NAMES = { const props = withDefaults(defineProps<{
MODAL: 'modal', enabled?: boolean,
FADE: 'fade', overflow?: boolean,
wide?: boolean,
transitionName?: 'modal' | 'fade',
variant?: 'default' | 'hint-modal' | 'scrolling',
}>(), {
enabled: true,
transitionName: 'modal',
variant: 'default',
})
defineEmits(['close', 'submit'])
// Based on https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/
function resetScrolling() {
const body = document.body
const scrollY = body.style.top
body.style.position = ''
body.style.top = ''
window.scrollTo(0, parseInt(scrollY || '0') * -1)
} }
export const VARIANTS = { watch(
DEFAULT: 'default', () => props.enabled,
HINT_MODAL: 'hint-modal', enabled => {
SCROLLING: 'scrolling', if (enabled) {
const scrollY = window.scrollY
document.body.style.position = 'fixed'
document.body.style.top = `-${scrollY}px`
} else {
resetScrolling()
} }
},
{
immediate: true,
},
)
function validValue(values) { onUnmounted(resetScrolling)
return (value) => Object.values(values).includes(value)
}
export default {
name: 'modal',
components: {
BaseButton,
},
props: {
enabled: {
type: Boolean,
default: true,
},
overflow: {
type: Boolean,
default: false,
},
wide: {
type: Boolean,
default: false,
},
transitionName: {
type: String,
default: TRANSITION_NAMES.MODAL,
validator: validValue(TRANSITION_NAMES),
},
variant: {
type: String,
default: VARIANTS.DEFAULT,
validator: validValue(VARIANTS),
},
},
emits: ['close', 'submit'],
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>