Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 58 additions & 43 deletions vue/src/ModalLink.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup>
import { modalPropNames, useModalStack, prefetch as prefetchModal } from './modalStack'
import { ref, provide, computed, watch, useAttrs, onBeforeUnmount, onMounted } from 'vue'
import { modalPropNames, prefetch as prefetchModal, useModalStack } from './modalStack'
import { computed, onBeforeUnmount, onMounted, provide, ref, useAttrs, watch } from 'vue'
import { only, rejectNullValues } from './helpers'
import { getConfig } from './config'
import { shouldIntercept } from '@inertiajs/core'

const props = defineProps({
href: {
Expand Down Expand Up @@ -126,26 +127,35 @@ function doPrefetch() {
})
}

function onMouseenter() {
if (!prefetchModes.value.includes('hover')) return
function onMouseenter(event) {
if (shouldIntercept(event)) {
event.preventDefault()
if (!prefetchModes.value.includes('hover')) return

hoverTimeout.value = setTimeout(() => {
doPrefetch()
}, 75) // Small delay to avoid prefetching on accidental hovers
hoverTimeout.value = setTimeout(() => {
doPrefetch()
}, 75) // Small delay to avoid prefetching on accidental hovers
}
}

function onMouseleave() {
if (hoverTimeout.value) {
clearTimeout(hoverTimeout.value)
hoverTimeout.value = null
function onMouseleave(event) {
if (shouldIntercept(event)) {
event.preventDefault()
if (hoverTimeout.value) {
clearTimeout(hoverTimeout.value)
hoverTimeout.value = null
}
}
}

function onMousedown(event) {
if (!prefetchModes.value.includes('click')) return
if (event.button !== 0) return // Only left click
if (shouldIntercept(event)) {
event.preventDefault()
if (!prefetchModes.value.includes('click')) return
if (event.button !== 0) return // Only left click

doPrefetch()
doPrefetch()
}
}

onMounted(() => {
Expand Down Expand Up @@ -200,36 +210,41 @@ function onAfterLeave() {
emit('after-leave')
}

function handle() {
if (loading.value) {
return
}
function handle(event) {
// Ensure the click is a standard click
if (shouldIntercept(event)) {
event.preventDefault()

if (!props.href.startsWith('#')) {
loading.value = true
emit('start')
}
if (loading.value) {
return
}

modalStack
.visit(
props.href,
props.method,
props.data,
props.headers,
rejectNullValues(only(props, modalPropNames)),
onClose,
onAfterLeave,
props.queryStringArrayFormat,
shouldNavigate.value,
)
.then((context) => {
modalContext.value = context
})
.catch((error) => {
console.error(error)
emit('error', error)
})
.finally(() => (loading.value = false))
if (!props.href.startsWith('#')) {
loading.value = true
emit('start')
}

modalStack
.visit(
props.href,
props.method,
props.data,
props.headers,
rejectNullValues(only(props, modalPropNames)),
onClose,
onAfterLeave,
props.queryStringArrayFormat,
shouldNavigate.value,
)
.then((context) => {
modalContext.value = context
})
.catch((error) => {
console.error(error)
emit('error', error)
})
.finally(() => (loading.value = false))
}
}
</script>

Expand All @@ -238,7 +253,7 @@ function handle() {
v-bind="$attrs"
:is="as"
:href="href"
@click.prevent="handle"
@click="handle"
@mouseenter="onMouseenter"
@mouseleave="onMouseleave"
@mousedown="onMousedown"
Expand Down