From 8cb51e44041e0d25812ac2517779f435944f6382 Mon Sep 17 00:00:00 2001 From: David Nahodyl Date: Tue, 12 Nov 2024 15:21:16 -0500 Subject: [PATCH 1/4] fix: make link href reactive --- packages/vue3/src/link.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/vue3/src/link.ts b/packages/vue3/src/link.ts index 49e5720bc..db9d7ad2d 100755 --- a/packages/vue3/src/link.ts +++ b/packages/vue3/src/link.ts @@ -10,7 +10,7 @@ import { router, shouldIntercept, } from '@inertiajs/core' -import { defineComponent, DefineComponent, h, onMounted, onUnmounted, PropType, ref } from 'vue' +import { computed, defineComponent, DefineComponent, h, onMounted, onUnmounted, PropType, ref, toRefs, watch } from 'vue' export interface InertiaLinkProps { as?: string @@ -181,15 +181,17 @@ const Link: InertiaLink = defineComponent({ const method = props.method.toLowerCase() as Method const as = method !== 'get' ? 'button' : props.as.toLowerCase() - const [href, data] = mergeDataIntoQueryString(method, props.href || '', props.data, props.queryStringArrayFormat) + const mergeDataArray = computed(() => mergeDataIntoQueryString(method, props.href || '', props.data, props.queryStringArrayFormat)) + const href = computed(() => mergeDataArray.value[0]) + const data = computed(() => mergeDataArray.value[1]) - const elProps = { - a: { href }, - button: { type: 'button' }, - } + const elProps = computed(() => { + a: { href: href.value } + button: { type: 'button' } + }) const baseParams = { - data: data, + data: data.value, method: method, replace: props.replace, preserveScroll: props.preserveScroll, @@ -219,14 +221,14 @@ const Link: InertiaLink = defineComponent({ } const prefetch = () => { - router.prefetch(href, baseParams, { cacheFor: cacheForValue }) + router.prefetch(href.value, baseParams, { cacheFor: cacheForValue }) } const regularEvents = { onClick: (event) => { if (shouldIntercept(event)) { event.preventDefault() - router.visit(href, visitParams) + router.visit(href.value, visitParams) } }, } @@ -252,7 +254,7 @@ const Link: InertiaLink = defineComponent({ }, onMouseup: (event) => { event.preventDefault() - router.visit(href, visitParams) + router.visit(href.value, visitParams) }, onClick: (event) => { if (shouldIntercept(event)) { @@ -267,7 +269,7 @@ const Link: InertiaLink = defineComponent({ as, { ...attrs, - ...(elProps[as] || {}), + ...(elProps.value[as] || {}), 'data-loading': inFlightCount.value > 0 ? '' : undefined, ...(() => { if (prefetchModes.includes('hover')) { From 8a73c9f00d5bcdce20572fb3e14240d826a8fe4e Mon Sep 17 00:00:00 2001 From: David Nahodyl Date: Tue, 12 Nov 2024 15:24:31 -0500 Subject: [PATCH 2/4] removed unused imports --- packages/vue3/src/link.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vue3/src/link.ts b/packages/vue3/src/link.ts index db9d7ad2d..96ada2c68 100755 --- a/packages/vue3/src/link.ts +++ b/packages/vue3/src/link.ts @@ -10,7 +10,7 @@ import { router, shouldIntercept, } from '@inertiajs/core' -import { computed, defineComponent, DefineComponent, h, onMounted, onUnmounted, PropType, ref, toRefs, watch } from 'vue' +import { computed, defineComponent, DefineComponent, h, onMounted, onUnmounted, PropType, ref } from 'vue' export interface InertiaLinkProps { as?: string From 7bc58a5b14e21071c2deefe104e3f070d52ca297 Mon Sep 17 00:00:00 2001 From: Joe Tannenbaum Date: Thu, 21 Nov 2024 11:14:00 -0500 Subject: [PATCH 3/4] fix elProps computer property --- packages/vue3/src/link.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/vue3/src/link.ts b/packages/vue3/src/link.ts index 96ada2c68..085498fb0 100755 --- a/packages/vue3/src/link.ts +++ b/packages/vue3/src/link.ts @@ -181,14 +181,16 @@ const Link: InertiaLink = defineComponent({ const method = props.method.toLowerCase() as Method const as = method !== 'get' ? 'button' : props.as.toLowerCase() - const mergeDataArray = computed(() => mergeDataIntoQueryString(method, props.href || '', props.data, props.queryStringArrayFormat)) + const mergeDataArray = computed(() => + mergeDataIntoQueryString(method, props.href || '', props.data, props.queryStringArrayFormat), + ) const href = computed(() => mergeDataArray.value[0]) const data = computed(() => mergeDataArray.value[1]) - const elProps = computed(() => { - a: { href: href.value } - button: { type: 'button' } - }) + const elProps = computed(() => ({ + a: { href: href.value }, + button: { type: 'button' }, + })) const baseParams = { data: data.value, From e3ed4ee80923bfd15dfe3b4d786b6929a99547dd Mon Sep 17 00:00:00 2001 From: Joe Tannenbaum Date: Thu, 21 Nov 2024 11:14:15 -0500 Subject: [PATCH 4/4] test for Link prop updating --- .../react/test-app/Pages/Links/PropUpdate.jsx | 15 +++++++++++++++ .../test-app/Pages/Links/PropUpdate.svelte | 16 ++++++++++++++++ .../vue3/test-app/Pages/Links/PropUpdate.vue | 13 +++++++++++++ tests/app/server.js | 3 ++- tests/links.spec.ts | 9 +++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 packages/react/test-app/Pages/Links/PropUpdate.jsx create mode 100644 packages/svelte/test-app/Pages/Links/PropUpdate.svelte create mode 100644 packages/vue3/test-app/Pages/Links/PropUpdate.vue diff --git a/packages/react/test-app/Pages/Links/PropUpdate.jsx b/packages/react/test-app/Pages/Links/PropUpdate.jsx new file mode 100644 index 000000000..4f2837598 --- /dev/null +++ b/packages/react/test-app/Pages/Links/PropUpdate.jsx @@ -0,0 +1,15 @@ +import { Link } from '@inertiajs/react' +import { useState } from 'react' + +export default () => { + const [href, setHref] = useState('/sleep') + + return ( +
+ + + The Link + +
+ ) +} diff --git a/packages/svelte/test-app/Pages/Links/PropUpdate.svelte b/packages/svelte/test-app/Pages/Links/PropUpdate.svelte new file mode 100644 index 000000000..e22ed5c60 --- /dev/null +++ b/packages/svelte/test-app/Pages/Links/PropUpdate.svelte @@ -0,0 +1,16 @@ + + +
+ + + The Link + +
diff --git a/packages/vue3/test-app/Pages/Links/PropUpdate.vue b/packages/vue3/test-app/Pages/Links/PropUpdate.vue new file mode 100644 index 000000000..4b792d5d7 --- /dev/null +++ b/packages/vue3/test-app/Pages/Links/PropUpdate.vue @@ -0,0 +1,13 @@ + + + diff --git a/tests/app/server.js b/tests/app/server.js index 213ccca6c..e17e23f3d 100644 --- a/tests/app/server.js +++ b/tests/app/server.js @@ -72,6 +72,7 @@ app.get('/links/headers/version', (req, res) => inertia.render(req, res, { component: 'Links/Headers', version: 'example-version-header' }), ) app.get('/links/data-loading', (req, res) => inertia.render(req, res, { component: 'Links/DataLoading' })) +app.get('/links/prop-update', (req, res) => inertia.render(req, res, { component: 'Links/PropUpdate' })) app.get('/visits/partial-reloads', (req, res) => inertia.render(req, res, { @@ -311,7 +312,7 @@ app.get('/deferred-props/page-2', (req, res) => { }) app.get('/svelte/props-and-page-store', (req, res) => - inertia.render(req, res, { component: 'Svelte/PropsAndPageStore', props: { foo: req.query.foo || 'default' }}), + inertia.render(req, res, { component: 'Svelte/PropsAndPageStore', props: { foo: req.query.foo || 'default' } }), ) app.all('/sleep', (req, res) => setTimeout(() => res.send(''), 2000)) diff --git a/tests/links.spec.ts b/tests/links.spec.ts index a45217788..adc8bda05 100644 --- a/tests/links.spec.ts +++ b/tests/links.spec.ts @@ -754,3 +754,12 @@ test.describe('data-loading attribute', () => { await expect(link2).not.toHaveAttribute('data-loading') }) }) + +test('will update href if prop is updated', async ({ page }) => { + await page.goto('/links/prop-update') + const link = await page.getByRole('link', { name: 'The Link' }) + const button = await page.getByRole('button', { name: 'Change URL' }) + await expect(link).toHaveAttribute('href', /\/sleep$/) + await button.click() + await expect(link).toHaveAttribute('href', /\/something-else$/) +})