@inertiajs/svelte 3.0.0-beta.5 → 3.0.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/App.svelte +23 -4
- package/dist/components/Form.svelte +3 -2
- package/dist/components/Form.svelte.d.ts +2 -2
- package/dist/components/InfiniteScroll.svelte +1 -0
- package/dist/components/createForm.d.ts +4 -2
- package/dist/createInertiaApp.d.ts +12 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/layoutProps.svelte.d.ts +3 -1
- package/dist/layoutProps.svelte.js +7 -5
- package/dist/types.d.ts +3 -3
- package/dist/useHttp.svelte.js +6 -4
- package/package.json +3 -3
- package/resources/boost/skills/inertia-svelte-development/SKILL.blade.php +57 -20
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<script lang="ts">
|
|
14
14
|
import type { Component } from 'svelte'
|
|
15
15
|
import type { LayoutType, LayoutResolver } from '../types'
|
|
16
|
-
import { normalizeLayouts } from '@inertiajs/core'
|
|
16
|
+
import { isPropsObject, normalizeLayouts } from '@inertiajs/core'
|
|
17
17
|
import { router } from '@inertiajs/core'
|
|
18
18
|
import Render, { h, type RenderProps } from './Render.svelte'
|
|
19
19
|
import { setPage } from '../page.svelte'
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
// Synchronous initialization so the global page store is populated during SSR
|
|
39
39
|
// ($effect.pre does not run during Svelte 5 SSR)
|
|
40
|
+
// svelte-ignore state_referenced_locally
|
|
40
41
|
setPage(page)
|
|
41
42
|
|
|
42
43
|
// Reactively update the global page state when local page state changes
|
|
@@ -99,6 +100,7 @@
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
let effectiveLayout: LayoutType | undefined
|
|
103
|
+
let callbackProps: Record<string, unknown> | null = null
|
|
102
104
|
const layoutValue = component.layout
|
|
103
105
|
|
|
104
106
|
if (
|
|
@@ -106,12 +108,24 @@
|
|
|
106
108
|
(layoutValue as Function).length <= 1 &&
|
|
107
109
|
typeof (layoutValue as Function).prototype === 'undefined'
|
|
108
110
|
) {
|
|
109
|
-
|
|
111
|
+
const result = (layoutValue as Function)(page.props)
|
|
112
|
+
|
|
113
|
+
if (isPropsObject(result, isComponent)) {
|
|
114
|
+
effectiveLayout = defaultLayout?.(page.component, page) as LayoutType | undefined
|
|
115
|
+
callbackProps = result as Record<string, unknown>
|
|
116
|
+
} else {
|
|
117
|
+
effectiveLayout = result as LayoutType | undefined
|
|
118
|
+
}
|
|
119
|
+
} else if (isPropsObject(layoutValue, isComponent)) {
|
|
120
|
+
effectiveLayout = defaultLayout?.(page.component, page) as LayoutType | undefined
|
|
121
|
+
callbackProps = layoutValue as Record<string, unknown>
|
|
110
122
|
} else {
|
|
111
123
|
effectiveLayout = (layoutValue ?? defaultLayout?.(page.component, page)) as LayoutType | undefined
|
|
112
124
|
}
|
|
113
125
|
|
|
114
|
-
return effectiveLayout
|
|
126
|
+
return effectiveLayout
|
|
127
|
+
? resolveLayout(effectiveLayout, child, page.props, key, !!component.layout && !callbackProps, callbackProps)
|
|
128
|
+
: child
|
|
115
129
|
}
|
|
116
130
|
|
|
117
131
|
function resolveLayout(
|
|
@@ -120,12 +134,17 @@
|
|
|
120
134
|
pageProps: PageProps,
|
|
121
135
|
key: number | null,
|
|
122
136
|
isFromPage: boolean = true,
|
|
137
|
+
callbackProps: Record<string, unknown> | null = null,
|
|
123
138
|
): RenderProps {
|
|
124
139
|
if (isFromPage && isRenderFunction(layout)) {
|
|
125
140
|
return (layout as LayoutResolver)(h, child)
|
|
126
141
|
}
|
|
127
142
|
|
|
128
|
-
|
|
143
|
+
let layouts = normalizeLayouts(layout, isComponent, isFromPage ? isRenderFunction : undefined)
|
|
144
|
+
|
|
145
|
+
if (callbackProps) {
|
|
146
|
+
layouts = layouts.map((l) => ({ ...l, props: { ...l.props, ...callbackProps } }))
|
|
147
|
+
}
|
|
129
148
|
|
|
130
149
|
if (layouts.length > 0) {
|
|
131
150
|
const dynamicProps = isServer ? { shared: {}, named: {} } : { shared: storeState.shared, named: storeState.named }
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { onMount } from 'svelte'
|
|
21
21
|
import { setFormContext } from './formContext'
|
|
22
22
|
import useForm from '../useForm.svelte'
|
|
23
|
+
import { config } from '..'
|
|
23
24
|
|
|
24
25
|
const noop = () => undefined
|
|
25
26
|
|
|
@@ -82,7 +83,7 @@
|
|
|
82
83
|
validateFiles = false,
|
|
83
84
|
validationTimeout = 1500,
|
|
84
85
|
optimistic,
|
|
85
|
-
withAllErrors =
|
|
86
|
+
withAllErrors = null,
|
|
86
87
|
component = undefined,
|
|
87
88
|
instant = false,
|
|
88
89
|
children,
|
|
@@ -292,7 +293,7 @@
|
|
|
292
293
|
form.withoutFileValidation()
|
|
293
294
|
}
|
|
294
295
|
|
|
295
|
-
if (withAllErrors) {
|
|
296
|
+
if (withAllErrors ?? config.get('form.withAllErrors')) {
|
|
296
297
|
form.withAllErrors()
|
|
297
298
|
}
|
|
298
299
|
})
|
|
@@ -42,10 +42,10 @@ declare const Form: import("svelte").Component<Props, {
|
|
|
42
42
|
resetAndClearErrors: (...fields: string[]) => void;
|
|
43
43
|
setError: (fieldOrFields: string | Record<string, string>, maybeValue?: string) => void;
|
|
44
44
|
defaults: () => void;
|
|
45
|
-
validate: (field?: string | NamedInputEvent | ValidationConfig, config?: ValidationConfig) => import("
|
|
45
|
+
validate: (field?: string | NamedInputEvent | ValidationConfig, config?: ValidationConfig) => import("..").InertiaFormProps<Record<string, any>> & Record<string, any> & import("../useForm.svelte").InertiaFormValidationProps<Record<string, any>>;
|
|
46
46
|
valid: (field: string) => boolean;
|
|
47
47
|
invalid: (field: string) => boolean;
|
|
48
|
-
touch: (field: string | NamedInputEvent | string[], ...fields: string[]) => import("
|
|
48
|
+
touch: (field: string | NamedInputEvent | string[], ...fields: string[]) => import("..").InertiaFormProps<Record<string, any>> & Record<string, any> & import("../useForm.svelte").InertiaFormValidationProps<Record<string, any>>;
|
|
49
49
|
touched: (field?: string) => boolean;
|
|
50
50
|
validator: () => Validator;
|
|
51
51
|
}, "action">;
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
let itemsElementRef: HTMLElement = $state(null!)
|
|
59
59
|
let startElementRef: HTMLElement = $state(null!)
|
|
60
60
|
let endElementRef: HTMLElement = $state(null!)
|
|
61
|
+
// svelte-ignore state_referenced_locally
|
|
61
62
|
const scrollProp = usePage().scrollProps?.[data]
|
|
62
63
|
|
|
63
64
|
let loadingPrevious = $state(false)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { FormComponentSlotProps } from '@inertiajs/core';
|
|
1
|
+
import type { FormComponentProps, FormComponentSlotProps } from '@inertiajs/core';
|
|
2
2
|
import type { Component, ComponentProps, Snippet } from 'svelte';
|
|
3
3
|
import Form from './Form.svelte';
|
|
4
|
-
type TypedFormComponent<TForm extends Record<string, any>> = Component<Omit<ComponentProps<typeof Form>, 'children'> & {
|
|
4
|
+
type TypedFormComponent<TForm extends Record<string, any>> = Component<Omit<ComponentProps<typeof Form>, 'children' | 'optimistic' | 'transform'> & {
|
|
5
|
+
optimistic?: FormComponentProps<TForm>['optimistic'];
|
|
6
|
+
transform?: FormComponentProps<TForm>['transform'];
|
|
5
7
|
children?: Snippet<[FormComponentSlotProps<TForm>]>;
|
|
6
8
|
}>;
|
|
7
9
|
export declare function createForm<TForm extends Record<string, any> = Record<string, any>>(): TypedFormComponent<TForm>;
|
|
@@ -10,17 +10,21 @@ type SetupOptions<SharedProps extends PageProps> = {
|
|
|
10
10
|
App: typeof App;
|
|
11
11
|
props: InertiaAppProps<SharedProps>;
|
|
12
12
|
};
|
|
13
|
+
type SvelteWithApp = (context: Map<any, any>, options: {
|
|
14
|
+
ssr: boolean;
|
|
15
|
+
}) => void;
|
|
13
16
|
type InertiaAppOptionsForCSR<SharedProps extends PageProps> = CreateInertiaAppOptionsForCSR<SharedProps, ComponentResolver, SetupOptions<SharedProps>, SvelteRenderResult | void, SvelteInertiaAppConfig> & {
|
|
14
|
-
withApp?:
|
|
15
|
-
ssr: boolean;
|
|
16
|
-
}) => void;
|
|
17
|
+
withApp?: never;
|
|
17
18
|
};
|
|
18
|
-
type InertiaAppOptionsAuto<SharedProps extends PageProps> = CreateInertiaAppOptions<ComponentResolver, SetupOptions<SharedProps>, SvelteRenderResult | void, SvelteInertiaAppConfig> & {
|
|
19
|
+
type InertiaAppOptionsAuto<SharedProps extends PageProps> = Omit<CreateInertiaAppOptions<ComponentResolver, SetupOptions<SharedProps>, SvelteRenderResult | void, SvelteInertiaAppConfig>, 'setup'> & {
|
|
19
20
|
page?: Page<SharedProps>;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
21
|
+
} & ({
|
|
22
|
+
setup?: undefined;
|
|
23
|
+
withApp?: SvelteWithApp;
|
|
24
|
+
} | {
|
|
25
|
+
setup: (options: SetupOptions<SharedProps>) => SvelteRenderResult | void;
|
|
26
|
+
withApp?: never;
|
|
27
|
+
});
|
|
24
28
|
type SvelteServerRender = (component: typeof App, options: {
|
|
25
29
|
props: InertiaAppProps<PageProps>;
|
|
26
30
|
context?: Map<any, any>;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { default as InfiniteScroll } from './components/InfiniteScroll.svelte';
|
|
|
8
8
|
export { default as Link } from './components/Link.svelte';
|
|
9
9
|
export { default as WhenVisible } from './components/WhenVisible.svelte';
|
|
10
10
|
export { default as createInertiaApp } from './createInertiaApp';
|
|
11
|
-
export { resetLayoutProps, setLayoutProps
|
|
11
|
+
export { resetLayoutProps, setLayoutProps } from './layoutProps.svelte';
|
|
12
12
|
export { default as inertia } from './link';
|
|
13
13
|
export { default as page, usePage } from './page.svelte';
|
|
14
14
|
export { type LayoutCallback, type ResolvedComponent, type SvelteInertiaAppConfig } from './types';
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { default as InfiniteScroll } from './components/InfiniteScroll.svelte';
|
|
|
9
9
|
export { default as Link } from './components/Link.svelte';
|
|
10
10
|
export { default as WhenVisible } from './components/WhenVisible.svelte';
|
|
11
11
|
export { default as createInertiaApp } from './createInertiaApp';
|
|
12
|
-
export { resetLayoutProps, setLayoutProps
|
|
12
|
+
export { resetLayoutProps, setLayoutProps } from './layoutProps.svelte';
|
|
13
13
|
export { default as inertia } from './link';
|
|
14
14
|
export { default as page, usePage } from './page.svelte';
|
|
15
15
|
export {} from './types';
|
|
@@ -4,5 +4,7 @@ export declare const storeState: {
|
|
|
4
4
|
named: Record<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
6
|
export declare function setLayoutProps(props: Partial<LayoutProps>): void;
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function setLayoutProps<K extends keyof NamedLayoutProps>(name: K, props: Partial<NamedLayoutProps[K]>): void;
|
|
8
|
+
export declare function setLayoutProps<T = never>(props: Partial<NoInfer<T>>): void;
|
|
9
|
+
export declare function setLayoutProps<T = never>(name: string, props: Partial<NoInfer<T>>): void;
|
|
8
10
|
export declare function resetLayoutProps(): void;
|
|
@@ -9,11 +9,13 @@ store.subscribe(() => {
|
|
|
9
9
|
storeState.shared = snapshot.shared;
|
|
10
10
|
storeState.named = snapshot.named;
|
|
11
11
|
});
|
|
12
|
-
export function setLayoutProps(props) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
export function setLayoutProps(nameOrProps, props) {
|
|
13
|
+
if (typeof nameOrProps === 'string') {
|
|
14
|
+
store.setFor(nameOrProps, props);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
store.set(nameOrProps);
|
|
18
|
+
}
|
|
17
19
|
}
|
|
18
20
|
export function resetLayoutProps() {
|
|
19
21
|
store.reset();
|
package/dist/types.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { type Page, type SharedPageProps } from '@inertiajs/core';
|
|
1
|
+
import { type LayoutCallbackReturn, type Page, type SharedPageProps } from '@inertiajs/core';
|
|
2
2
|
import type { Component } from 'svelte';
|
|
3
3
|
import type { RenderFunction, RenderProps } from './components/Render.svelte';
|
|
4
4
|
export type ComponentResolver = (name: string, page?: Page<SharedPageProps>) => ResolvedComponent | Promise<ResolvedComponent>;
|
|
5
5
|
export type LayoutResolver = (h: RenderFunction, page: RenderProps) => RenderProps;
|
|
6
|
-
export type LayoutCallback = (props: SharedPageProps) =>
|
|
6
|
+
export type LayoutCallback = (props: SharedPageProps) => LayoutCallbackReturn<Component>;
|
|
7
7
|
export type LayoutTuple = [Component, Record<string, unknown>?];
|
|
8
8
|
export type LayoutObject = {
|
|
9
9
|
component: Component;
|
|
10
10
|
props?: Record<string, unknown>;
|
|
11
11
|
};
|
|
12
12
|
export type NamedLayouts = Record<string, Component | LayoutTuple | LayoutObject>;
|
|
13
|
-
export type LayoutType = LayoutResolver |
|
|
13
|
+
export type LayoutType = LayoutResolver | ((props: any) => any) | Component | Component[] | LayoutTuple | LayoutObject | NamedLayouts | (Component | LayoutTuple | LayoutObject)[];
|
|
14
14
|
export type ResolvedComponent = {
|
|
15
15
|
default: Component;
|
|
16
16
|
layout?: LayoutType;
|
package/dist/useHttp.svelte.js
CHANGED
|
@@ -31,10 +31,12 @@ export default function useHttp(...args) {
|
|
|
31
31
|
if (options.optimistic) {
|
|
32
32
|
snapshot = cloneDeep(form.data());
|
|
33
33
|
const optimisticData = options.optimistic(cloneDeep(snapshot));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
if (optimisticData) {
|
|
35
|
+
Object.keys(optimisticData).forEach((key) => {
|
|
36
|
+
;
|
|
37
|
+
baseForm[key] = optimisticData[key];
|
|
38
|
+
});
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
41
|
setFormState('processing', true);
|
|
40
42
|
options.onStart?.();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inertiajs/svelte",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "The Svelte adapter for Inertia.js",
|
|
6
6
|
"contributors": [
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"es-toolkit": "^1.33.0",
|
|
57
|
-
"laravel-precognition": "2.0.0
|
|
58
|
-
"@inertiajs/core": "3.0.0-beta.
|
|
57
|
+
"laravel-precognition": "^2.0.0",
|
|
58
|
+
"@inertiajs/core": "3.0.0-beta.7"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "pnpm package && svelte-check --tsconfig ./tsconfig.json && publint",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: inertia-svelte-development
|
|
3
|
-
description: "Develops Inertia.js v3 Svelte 5 client-side applications. Activates when creating Svelte pages, forms, or navigation; using Link, Form, useForm, useHttp,
|
|
3
|
+
description: "Develops Inertia.js v3 Svelte 5 client-side applications. Activates when creating Svelte pages, forms, or navigation; using Link, Form, useForm, useHttp, setLayoutProps, or router; working with deferred props, prefetching, optimistic updates, instant visits, or polling; or when user mentions Svelte with Inertia, Svelte pages, Svelte forms, or Svelte navigation."
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: laravel
|
|
@@ -379,18 +379,11 @@ Share dynamic data between pages and persistent layouts:
|
|
|
379
379
|
|
|
380
380
|
@boostsnippet("Layout Props in Layout", "svelte")
|
|
381
381
|
<script>
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const layout = useLayoutProps({
|
|
385
|
-
title: 'My App',
|
|
386
|
-
showSidebar: true,
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
let { children } = $props()
|
|
382
|
+
let { title = 'My App', showSidebar = true, children } = $props()
|
|
390
383
|
</script>
|
|
391
384
|
|
|
392
|
-
<header>{
|
|
393
|
-
{#if
|
|
385
|
+
<header>{title}</header>
|
|
386
|
+
{#if showSidebar}
|
|
394
387
|
<aside>Sidebar</aside>
|
|
395
388
|
{/if}
|
|
396
389
|
<main>
|
|
@@ -439,30 +432,54 @@ let { users } = $props()
|
|
|
439
432
|
|
|
440
433
|
### Polling
|
|
441
434
|
|
|
442
|
-
|
|
435
|
+
Use the `usePoll` hook to automatically refresh data at intervals. It handles cleanup on unmount and throttles polling when the tab is inactive.
|
|
443
436
|
|
|
444
|
-
@boostsnippet("Polling
|
|
437
|
+
@boostsnippet("Basic Polling", "svelte")
|
|
445
438
|
<script>
|
|
446
|
-
import {
|
|
447
|
-
import { onMount } from 'svelte'
|
|
439
|
+
import { usePoll } from '@inertiajs/svelte'
|
|
448
440
|
|
|
449
441
|
let { stats } = $props()
|
|
450
442
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
443
|
+
usePoll(5000)
|
|
444
|
+
</script>
|
|
445
|
+
|
|
446
|
+
<div>
|
|
447
|
+
<h1>Dashboard</h1>
|
|
448
|
+
<div>Active Users: {stats.activeUsers}</div>
|
|
449
|
+
</div>
|
|
450
|
+
@endboostsnippet
|
|
451
|
+
|
|
452
|
+
@boostsnippet("Polling With Request Options and Manual Control", "svelte")
|
|
453
|
+
<script>
|
|
454
|
+
import { usePoll } from '@inertiajs/svelte'
|
|
455
|
+
|
|
456
|
+
let { stats } = $props()
|
|
455
457
|
|
|
456
|
-
|
|
458
|
+
const { start, stop } = usePoll(5000, {
|
|
459
|
+
only: ['stats'],
|
|
460
|
+
onStart() {
|
|
461
|
+
console.log('Polling request started')
|
|
462
|
+
},
|
|
463
|
+
onFinish() {
|
|
464
|
+
console.log('Polling request finished')
|
|
465
|
+
},
|
|
466
|
+
}, {
|
|
467
|
+
autoStart: false,
|
|
468
|
+
keepAlive: true,
|
|
457
469
|
})
|
|
458
470
|
</script>
|
|
459
471
|
|
|
460
472
|
<div>
|
|
461
473
|
<h1>Dashboard</h1>
|
|
462
474
|
<div>Active Users: {stats.activeUsers}</div>
|
|
475
|
+
<button onclick={start}>Start Polling</button>
|
|
476
|
+
<button onclick={stop}>Stop Polling</button>
|
|
463
477
|
</div>
|
|
464
478
|
@endboostsnippet
|
|
465
479
|
|
|
480
|
+
- `autoStart` (default `true`) - set to `false` to start polling manually via the returned `start()` function
|
|
481
|
+
- `keepAlive` (default `false`) - set to `true` to prevent throttling when the browser tab is inactive
|
|
482
|
+
|
|
466
483
|
### WhenVisible
|
|
467
484
|
|
|
468
485
|
Lazy-load a prop when an element scrolls into view. Useful for deferring expensive data that sits below the fold:
|
|
@@ -490,6 +507,26 @@ let { stats } = $props()
|
|
|
490
507
|
</div>
|
|
491
508
|
@endboostsnippet
|
|
492
509
|
|
|
510
|
+
### InfiniteScroll
|
|
511
|
+
|
|
512
|
+
Automatically load additional pages of paginated data as users scroll:
|
|
513
|
+
|
|
514
|
+
@boostsnippet("InfiniteScroll Example", "svelte")
|
|
515
|
+
<script>
|
|
516
|
+
import { InfiniteScroll } from '@inertiajs/svelte'
|
|
517
|
+
|
|
518
|
+
let { users } = $props()
|
|
519
|
+
</script>
|
|
520
|
+
|
|
521
|
+
<InfiniteScroll data="users">
|
|
522
|
+
{#each users.data as user (user.id)}
|
|
523
|
+
<div>{user.name}</div>
|
|
524
|
+
{/each}
|
|
525
|
+
</InfiniteScroll>
|
|
526
|
+
@endboostsnippet
|
|
527
|
+
|
|
528
|
+
The server must use `Inertia::scroll()` to configure the paginated data. Use the `search-docs` tool with a query of `infinite scroll` for detailed guidance on buffers, manual loading, reverse mode, and custom trigger elements.
|
|
529
|
+
|
|
493
530
|
## Server-Side Patterns
|
|
494
531
|
|
|
495
532
|
Server-side patterns (Inertia::render, props, middleware) are covered in inertia-laravel guidelines.
|