feat: prevent scrolling the rest of the page when a modal is open #1617
|
@ -8,6 +8,7 @@
|
||||||
{ 'has-overflow': overflow },
|
{ 'has-overflow': overflow },
|
||||||
variant,
|
variant,
|
||||||
]"
|
]"
|
||||||
|
ref="modal"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="modal-container"
|
class="modal-container"
|
||||||
|
@ -60,57 +61,37 @@
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
import BaseButton from '@/components/base/BaseButton.vue'
|
import BaseButton from '@/components/base/BaseButton.vue'
|
||||||
|
import {ref, watch} from 'vue'
|
||||||
|
import {useScrollLock} from '@vueuse/core'
|
||||||
|
|
||||||
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',
|
||||||
|
})
|
||||||
|
|
||||||
export const VARIANTS = {
|
defineEmits(['close', 'submit'])
|
||||||
DEFAULT: 'default',
|
|
||||||
HINT_MODAL: 'hint-modal',
|
|
||||||
SCROLLING: 'scrolling',
|
|
||||||
}
|
|
||||||
|
|
||||||
function validValue(values) {
|
const modal = ref<HTMLElement | null>(null)
|
||||||
|
|||||||
return (value) => Object.values(values).includes(value)
|
const scrollLock = useScrollLock(modal)
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
watch(
|
||||||
name: 'modal',
|
() => props.enabled,
|
||||||
|
enabled => {
|
||||||
components: {
|
scrollLock.value = enabled
|
||||||
BaseButton,
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
props: {
|
immediate: true,
|
||||||
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>
|
||||||
|
|
Reference in New Issue
Block a user
Why not:
Don't I need to specify the default value?
The default would be
undefined
in that case. Meaning:ref<HTMLElement>()
is identical toref<HTMLElement | undefined>(undefined)
Ohh okay, that makes sense. I'm kind of used to setting everything to
null
if its not defined, coming from the backend. Butundefined
makes more sense in the js world.