Added resizing logics to modal + option to disable this

This commit is contained in:
Dennis Postma 2024-06-10 01:42:57 +02:00
parent 7e11a86604
commit 2f7153fbfe
3 changed files with 86 additions and 3 deletions

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 15L15 21M21 8L8 21" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 346 B

View File

@ -122,6 +122,7 @@ async function registerFunc() {
flex-direction: column; flex-direction: column;
background-color: rgba($white, 0.5); background-color: rgba($white, 0.5);
border-radius: 3px; border-radius: 3px;
border: $light-gray 1px solid;
min-width: 400px; min-width: 400px;
margin: 0 auto; margin: 0 auto;

View File

@ -1,6 +1,6 @@
<template> <template>
<Teleport to="body"> <Teleport to="body">
<div class="modal-container" :style="{ top: y + 'px', left: x + 'px' }" v-if="isModalOpenRef"> <div class="modal-container" v-if="isModalOpenRef" :style="{ top: y + 'px', left: x + 'px', width: width + 'px', height: height + 'px' }">
<div class="modal-header" @mousedown="startDrag"> <div class="modal-header" @mousedown="startDrag">
<slot name="modalHeader" /> <slot name="modalHeader" />
<div class="buttons"> <div class="buttons">
@ -10,6 +10,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<slot name="modalBody" /> <slot name="modalBody" />
<img v-if="isResizable" src="/assets/icons/resize-icon.svg" alt="resize" class="resize" @mousedown="startResize" />
</div> </div>
<div v-if="$slots.modalFooter" class="modal-footer"> <div v-if="$slots.modalFooter" class="modal-footer">
<slot name="modalFooter" /> <slot name="modalFooter" />
@ -29,6 +30,18 @@ const properties = defineProps({
closable: { closable: {
type: Boolean, type: Boolean,
default: true default: true
},
isResizable: {
type: Boolean,
default: true
},
modalWidth: {
type: Number,
default: 500
},
modalHeight: {
type: Number,
default: 280
} }
}) })
@ -46,6 +59,35 @@ function close() {
emit('modal:close') emit('modal:close')
} }
// (re)size logics
const width = ref(properties.modalWidth)
const height = ref(properties.modalHeight)
let minWidth = ref(200)
let minHeight = ref(100)
let isResizing = ref(false)
let startWidth = 0
let startHeight = 0
const startResize = (event: MouseEvent) => {
isResizing.value = true
startWidth = width.value - event.clientX
startHeight = height.value - event.clientY
event.preventDefault()
}
const resizeModal = (event: MouseEvent) => {
if (!isResizing.value) return
let newWidth = startWidth + event.clientX
let newHeight = startHeight + event.clientY
width.value = newWidth > minWidth.value ? newWidth : minWidth.value
height.value = newHeight > minHeight.value ? newHeight : minHeight.value
}
const stopResize = () => {
isResizing.value = false
}
// make modal draggable // make modal draggable
let startX = 0 let startX = 0
let startY = 0 let startY = 0
@ -85,13 +127,41 @@ const stopDrag = () => {
onMounted(() => { onMounted(() => {
addEventListener('mousemove', drag) addEventListener('mousemove', drag)
addEventListener('mouseup', stopDrag) addEventListener('mouseup', stopDrag)
addEventListener('mousemove', resizeModal)
addEventListener('mouseup', stopResize)
addEventListener('resize', handleResize)
}) })
onUnmounted(() => { onUnmounted(() => {
removeEventListener('mousemove', drag) removeEventListener('mousemove', drag)
removeEventListener('mouseup', stopDrag) removeEventListener('mouseup', stopDrag)
removeEventListener('mousemove', resizeModal)
removeEventListener('mouseup', stopResize)
removeEventListener('resize', handleResize)
}) })
// Make sure modal doesn't go off screen
watch(
() => x.value, (value) => {
if (value < 0) { x.value = 0 } else if (value + width.value > window.innerWidth) { x.value = window.innerWidth - width.value }
}
)
watch(
() => y.value, (value) => {
if (value < 0) { y.value = 0 } else if (value + height.value > window.innerHeight) { y.value = window.innerHeight - height.value }
}
)
// also on window resize function
function handleResize() {
if (x.value + width.value > window.innerWidth) {
x.value = window.innerWidth - width.value
}
if (y.value + height.value > window.innerHeight) {
y.value = window.innerHeight - height.value
}
}
</script> </script>
<style lang="scss"> <style lang="scss">
@ -102,8 +172,6 @@ onUnmounted(() => {
top: 0; top: 0;
left: 0; left: 0;
max-width: 1000px; max-width: 1000px;
min-width: 500px;
min-height: 280px;
background-color: rgba($dark-gray, 0.8); background-color: rgba($dark-gray, 0.8);
border: 2px solid $dark-cyan; border: 2px solid $dark-cyan;
z-index: 999; z-index: 999;
@ -158,6 +226,16 @@ onUnmounted(() => {
padding: 15px; padding: 15px;
flex-grow: 1; flex-grow: 1;
.resize {
filter: invert(60%);
position: absolute;
bottom: 0;
right: 0;
width: 20px;
height: 20px;
cursor: nwse-resize;
}
.submit { .submit {
display: inline-block; display: inline-block;
button { button {