Skip to content

Commit 69292ef

Browse files
committed
Update Svelte adapter
Enhance TypeScript support in Svelte 1.x using insights from the work done on 2.0.
1 parent 9476aa5 commit 69292ef

File tree

5 files changed

+46
-29
lines changed

5 files changed

+46
-29
lines changed

packages/svelte/src/components/App.svelte

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import type { ComponentType } from 'svelte'
2+
import type { LayoutType } from '../types'
33
import type { PageProps } from '@inertiajs/core'
44
import type { RenderProps } from './Render.svelte'
55
import Render, { h } from './Render.svelte'
@@ -11,8 +11,6 @@
1111
* Resolves the render props for the current page component, including layouts.
1212
*/
1313
function resolveProps({ component, page, key = null }: InertiaStore): RenderProps {
14-
if (!component?.default || !page) return null
15-
1614
const child = h(component.default, page.props, [], key)
1715
const layout = component.layout
1816
@@ -39,16 +37,16 @@
3937
* }
4038
*/
4139
function resolveLayout(
42-
layout: ComponentType,
40+
layout: LayoutType,
4341
child: RenderProps,
4442
pageProps: PageProps,
4543
key: number | null,
4644
): RenderProps {
4745
if (Array.isArray(layout)) {
4846
return layout
49-
.concat(child)
47+
.slice()
5048
.reverse()
51-
.reduce((child, layout) => h(layout, pageProps, [child], key))
49+
.reduce((currentRender, layoutComponent) => h(layoutComponent, pageProps, [currentRender], key), child)
5250
}
5351
5452
return h(layout, pageProps, child ? [child] : [], key)

packages/svelte/src/components/Link.svelte

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
<script lang="ts">
2-
import type { Method, PreserveStateOption, RequestPayload } from '@inertiajs/core'
3-
import { beforeUpdate } from 'svelte'
2+
import type { FormDataConvertible, Method, PreserveStateOption } from '@inertiajs/core'
43
import { inertia } from '../index'
54
65
export let href: string
76
export let as: keyof HTMLElementTagNameMap = 'a'
8-
export let data: RequestPayload = {}
7+
export let data: Record<string, FormDataConvertible> = {}
98
export let method: Method = 'get'
109
export let replace: boolean = false
1110
export let preserveScroll: PreserveStateOption = false
@@ -15,13 +14,12 @@
1514
export let headers: Record<string, string> = {}
1615
export let queryStringArrayFormat: 'brackets' | 'indices' = 'brackets'
1716
18-
beforeUpdate(() => {
19-
if (as === 'a' && method.toLowerCase() !== 'get') {
20-
console.warn(
21-
`Creating POST/PUT/PATCH/DELETE <a> links is discouraged as it causes "Open Link in New Tab/Window" accessibility issues.\n\nPlease specify a more appropriate element using the "as" attribute. For example:\n\n<Link href="${href}" method="${method}" as="button">...</Link>`,
22-
)
23-
}
24-
})
17+
$: asProp = method !== 'get' ? 'button' : as.toLowerCase()
18+
$: elProps =
19+
{
20+
a: { href },
21+
button: { type: 'button' },
22+
}[asProp] || {}
2523
</script>
2624

2725
<!-- svelte-ignore a11y-no-static-element-interactions -->
@@ -39,8 +37,8 @@
3937
headers,
4038
queryStringArrayFormat,
4139
}}
42-
{...as === 'a' ? { href } : {}}
4340
{...$$restProps}
41+
{...elProps}
4442
on:focus
4543
on:blur
4644
on:click

packages/svelte/src/link.ts

+25-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
1-
import { mergeDataIntoQueryString, router, shouldIntercept, type VisitOptions } from '@inertiajs/core'
2-
import type { Action } from 'svelte/action'
1+
import {
2+
mergeDataIntoQueryString,
3+
router,
4+
shouldIntercept,
5+
type FormDataConvertible,
6+
type GlobalEventsMap,
7+
type VisitOptions,
8+
} from '@inertiajs/core'
9+
import type { CancelTokenSource } from 'axios'
10+
import type { ActionReturn } from 'svelte/action'
311

412
interface ActionElement extends HTMLElement {
513
href?: string
614
}
715

8-
type ActionParameters = VisitOptions & { href?: string }
16+
type ActionParameters = Omit<VisitOptions, 'data'> & {
17+
href?: string
18+
data?: Record<string, FormDataConvertible>
19+
}
20+
21+
type SelectedEventKeys = 'start' | 'progress' | 'finish' | 'before' | 'cancel' | 'success' | 'error'
22+
type SelectedGlobalEventsMap = Pick<GlobalEventsMap, SelectedEventKeys>
23+
type ActionAttributes = {
24+
[K in keyof SelectedGlobalEventsMap as `on:${K}`]?: CustomEvent<SelectedGlobalEventsMap[K]['details']>
25+
} & {
26+
'on:cancel-token'?: CustomEvent<CancelTokenSource>
27+
}
928

10-
const link: Action<ActionElement, ActionParameters> = (node, options = {}) => {
29+
function link(node: ActionElement, options: ActionParameters = {}): ActionReturn<ActionParameters, ActionAttributes> {
1130
const [href, data] = hrefAndData(options)
1231
node.href = href
1332
options.data = data
@@ -34,8 +53,8 @@ const link: Action<ActionElement, ActionParameters> = (node, options = {}) => {
3453
event.preventDefault()
3554

3655
router.visit(node.href, {
37-
onCancelToken: () => fireEvent('cancel-token'),
38-
onBefore: (visit) => fireEvent('before', { detail: { visit } }),
56+
onCancelToken: (token) => fireEvent('cancel-token', { detail: { token } }),
57+
onBefore: (visit) => fireEvent('before', { cancelable: true, detail: { visit } }),
3958
onStart: (visit) => fireEvent('start', { detail: { visit } }),
4059
onProgress: (progress) => fireEvent('progress', { detail: { progress } }),
4160
onFinish: (visit) => fireEvent('finish', { detail: { visit } }),

packages/svelte/src/store.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { writable } from 'svelte/store'
33
import type { ResolvedComponent } from './types'
44

55
export interface InertiaStore {
6-
component: ResolvedComponent | null
7-
page: Page | null
6+
component: ResolvedComponent
7+
page: Page
88
key: number | null
99
}
1010

1111
const store = writable<InertiaStore>({
12-
component: null,
13-
page: null,
12+
component: null as unknown as ResolvedComponent,
13+
page: null as unknown as Page,
1414
key: null,
1515
})
1616

packages/svelte/src/types.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import type { ComponentType } from 'svelte'
22

33
export type ComponentResolver = (name: string) => ResolvedComponent | Promise<ResolvedComponent>
44

5+
export type LayoutType = ComponentType | ComponentType[]
6+
57
export type ResolvedComponent = {
6-
default?: ComponentType
7-
layout?: ComponentType
8+
default: ComponentType
9+
layout?: LayoutType
810
}

0 commit comments

Comments
 (0)