@inertiajs/react 1.0.0-beta.4 → 1.0.0-beta.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inertiajs/react",
3
- "version": "1.0.0-beta.4",
3
+ "version": "1.0.0-beta.5",
4
4
  "license": "MIT",
5
5
  "description": "The React adapter for Inertia.js",
6
6
  "contributors": [
@@ -16,6 +16,10 @@
16
16
  "bugs": {
17
17
  "url": "https://github.com/inertiajs/inertia/issues"
18
18
  },
19
+ "files": [
20
+ "dist",
21
+ "types"
22
+ ],
19
23
  "source": "src/index.ts",
20
24
  "main": "dist/index.js",
21
25
  "types": "types/index.d.ts",
@@ -48,7 +52,7 @@
48
52
  "react": "^16.9.0 || ^17.0.0 || ^18.0.0"
49
53
  },
50
54
  "dependencies": {
51
- "@inertiajs/core": "1.0.0-beta.4",
55
+ "@inertiajs/core": "1.0.0-beta.5",
52
56
  "lodash.isequal": "^4.5.0"
53
57
  }
54
58
  }
package/types/App.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ declare function App({ children, initialPage, initialComponent, resolveComponent, titleCallback, onHeadUpdate, }: {
2
+ children: any;
3
+ initialPage: any;
4
+ initialComponent: any;
5
+ resolveComponent: any;
6
+ titleCallback: any;
7
+ onHeadUpdate: any;
8
+ }): import("react").FunctionComponentElement<import("react").ProviderProps<any>>;
9
+ declare namespace App {
10
+ var displayName: string;
11
+ }
12
+ export default App;
@@ -0,0 +1,7 @@
1
+ import { FunctionComponent } from 'react';
2
+ type InertiaHeadProps = {
3
+ title?: string;
4
+ };
5
+ type InertiaHead = FunctionComponent<InertiaHeadProps>;
6
+ declare const Head: InertiaHead;
7
+ export default Head;
@@ -0,0 +1,2 @@
1
+ declare const headContext: import("react").Context<any>;
2
+ export default headContext;
@@ -0,0 +1,26 @@
1
+ import { FormDataConvertible, Method, PreserveStateOption, Progress } from '@inertiajs/core';
2
+ interface BaseInertiaLinkProps {
3
+ as?: string;
4
+ data?: Record<string, FormDataConvertible>;
5
+ href: string;
6
+ method?: Method;
7
+ headers?: Record<string, string>;
8
+ onClick?: (event: React.MouseEvent<HTMLAnchorElement> | React.KeyboardEvent<HTMLAnchorElement>) => void;
9
+ preserveScroll?: PreserveStateOption;
10
+ preserveState?: PreserveStateOption;
11
+ replace?: boolean;
12
+ only?: string[];
13
+ onCancelToken?: (cancelToken: import('axios').CancelTokenSource) => void;
14
+ onBefore?: () => void;
15
+ onStart?: () => void;
16
+ onProgress?: (progress: Progress) => void;
17
+ onFinish?: () => void;
18
+ onCancel?: () => void;
19
+ onSuccess?: () => void;
20
+ onError?: () => void;
21
+ queryStringArrayFormat?: 'indices' | 'brackets';
22
+ }
23
+ type InertiaLinkProps = BaseInertiaLinkProps & Omit<React.HTMLAttributes<HTMLElement>, keyof BaseInertiaLinkProps> & Omit<React.AllHTMLAttributes<HTMLElement>, keyof BaseInertiaLinkProps>;
24
+ type InertiaLink = React.FunctionComponent<InertiaLinkProps>;
25
+ declare const Link: InertiaLink;
26
+ export default Link;
@@ -0,0 +1,2 @@
1
+ declare const pageContext: import("react").Context<any>;
2
+ export default pageContext;
@@ -0,0 +1,56 @@
1
+ import { Page, PageProps, PageResolver } from '@inertiajs/core';
2
+ import { ComponentType, FunctionComponent, Key, ReactElement, ReactNode } from 'react';
3
+ import { renderToString } from 'react-dom/server';
4
+ type ReactInstance = ReactElement;
5
+ type ReactComponent = ReactNode;
6
+ type HeadManagerOnUpdate = (elements: string[]) => void;
7
+ type HeadManagerTitleCallback = (title: string) => string;
8
+ type AppType<SharedProps = PageProps> = FunctionComponent<{
9
+ children?: (props: {
10
+ Component: ComponentType;
11
+ key: Key;
12
+ props: Page<SharedProps>['props'];
13
+ }) => ReactNode;
14
+ } & SetupOptions<unknown, SharedProps>['props']>;
15
+ export type SetupOptions<ElementType, SharedProps> = {
16
+ el: ElementType;
17
+ App: AppType;
18
+ props: {
19
+ initialPage: Page<SharedProps>;
20
+ initialComponent: ReactComponent;
21
+ resolveComponent: PageResolver;
22
+ titleCallback?: HeadManagerTitleCallback;
23
+ onHeadUpdate?: HeadManagerOnUpdate;
24
+ };
25
+ };
26
+ type BaseInertiaAppOptions = {
27
+ title?: HeadManagerTitleCallback;
28
+ resolve: PageResolver;
29
+ };
30
+ type CreateInertiaAppSetupReturnType = ReactInstance | void;
31
+ type InertiaAppOptionsForCSR<SharedProps> = BaseInertiaAppOptions & {
32
+ id?: string;
33
+ page?: Page | string;
34
+ render?: undefined;
35
+ progress?: false | {
36
+ delay?: number;
37
+ color?: string;
38
+ includeCSS?: boolean;
39
+ showSpinner?: boolean;
40
+ };
41
+ setup(options: SetupOptions<HTMLElement, SharedProps>): CreateInertiaAppSetupReturnType;
42
+ };
43
+ type CreateInertiaAppSSRContent = {
44
+ head: string[];
45
+ body: string;
46
+ };
47
+ type InertiaAppOptionsForSSR<SharedProps> = BaseInertiaAppOptions & {
48
+ id?: undefined;
49
+ page: Page | string;
50
+ render: typeof renderToString;
51
+ progress: undefined;
52
+ setup(options: SetupOptions<null, SharedProps>): ReactInstance;
53
+ };
54
+ export default function createInertiaApp<SharedProps = PageProps>(options: InertiaAppOptionsForCSR<SharedProps>): Promise<CreateInertiaAppSetupReturnType>;
55
+ export default function createInertiaApp<SharedProps = PageProps>(options: InertiaAppOptionsForSSR<SharedProps>): Promise<CreateInertiaAppSSRContent>;
56
+ export {};
@@ -0,0 +1,7 @@
1
+ export declare const router: import("@inertiajs/core").Router;
2
+ export { default as createInertiaApp } from './createInertiaApp';
3
+ export { default as Head } from './Head';
4
+ export { default as Link } from './Link';
5
+ export { default as useForm } from './useForm';
6
+ export { default as usePage } from './usePage';
7
+ export { default as useRemember } from './useRemember';
@@ -0,0 +1,33 @@
1
+ import { Method, Progress, VisitOptions } from '@inertiajs/core';
2
+ type setDataByObject<TForm> = (data: TForm) => void;
3
+ type setDataByMethod<TForm> = (data: (previousData: TForm) => TForm) => void;
4
+ type setDataByKeyValuePair<TForm> = <K extends keyof TForm>(key: K, value: TForm[K]) => void;
5
+ export interface InertiaFormProps<TForm extends Record<string, unknown>> {
6
+ data: TForm;
7
+ isDirty: boolean;
8
+ errors: Partial<Record<keyof TForm, string>>;
9
+ hasErrors: boolean;
10
+ processing: boolean;
11
+ progress: Progress | null;
12
+ wasSuccessful: boolean;
13
+ recentlySuccessful: boolean;
14
+ setData: setDataByObject<TForm> & setDataByMethod<TForm> & setDataByKeyValuePair<TForm>;
15
+ transform: (callback: (data: TForm) => TForm) => void;
16
+ setDefaults(): void;
17
+ setDefaults(field: keyof TForm, value: string): void;
18
+ setDefaults(fields: Record<keyof TForm, string>): void;
19
+ reset: (...fields: (keyof TForm)[]) => void;
20
+ clearErrors: (...fields: (keyof TForm)[]) => void;
21
+ setError(field: keyof TForm, value: string): void;
22
+ setError(errors: Record<keyof TForm, string>): void;
23
+ submit: (method: Method, url: string, options?: VisitOptions) => void;
24
+ get: (url: string, options?: VisitOptions) => void;
25
+ patch: (url: string, options?: VisitOptions) => void;
26
+ post: (url: string, options?: VisitOptions) => void;
27
+ put: (url: string, options?: VisitOptions) => void;
28
+ delete: (url: string, options?: VisitOptions) => void;
29
+ cancel: () => void;
30
+ }
31
+ export default function useForm<TForm extends Record<string, unknown>>(initialValues?: TForm): InertiaFormProps<TForm>;
32
+ export default function useForm<TForm extends Record<string, unknown>>(rememberKey: string, initialValues?: TForm): InertiaFormProps<TForm>;
33
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Page } from '@inertiajs/core';
2
+ export default function usePage(): Page;
@@ -0,0 +1,3 @@
1
+ import { Dispatch, SetStateAction } from 'react';
2
+ export default function useRemember<State>(initialState: State, key?: string): [State, Dispatch<SetStateAction<State>>];
3
+ export declare function useRememberedState<State>(initialState: State, key?: string): [State, Dispatch<SetStateAction<State>>];
package/build.js DELETED
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env node
2
- const esbuild = require('esbuild')
3
- const { nodeExternalsPlugin } = require('esbuild-node-externals')
4
-
5
- const watch = process.argv.slice(1).includes('--watch')
6
-
7
- const config = {
8
- bundle: true,
9
- minify: true,
10
- sourcemap: true,
11
- target: 'es2020',
12
- plugins: [nodeExternalsPlugin()],
13
- }
14
-
15
- const builds = [
16
- { entryPoints: ['src/index.ts'], format: 'esm', outfile: 'dist/index.esm.js', platform: 'browser' },
17
- { entryPoints: ['src/index.ts'], format: 'cjs', outfile: 'dist/index.js', platform: 'browser' },
18
- { entryPoints: ['src/server.ts'], format: 'esm', outfile: 'dist/server.esm.js', platform: 'node' },
19
- { entryPoints: ['src/server.ts'], format: 'cjs', outfile: 'dist/server.js', platform: 'node' },
20
- ]
21
-
22
- builds.forEach((build) => {
23
- esbuild
24
- .build({ ...config, ...build, ...watcher(build) })
25
- .then(() => console.log(`${watch ? 'Watching' : 'Built'} ${build.entryPoints} (${build.format})…`))
26
- .catch(() => process.exit(1))
27
- })
28
-
29
- function watcher(build) {
30
- return watch
31
- ? {
32
- watch: {
33
- onRebuild: (error) =>
34
- error
35
- ? console.error('Watch failed:', error)
36
- : console.log(`Rebuilding ${build.entryPoints} (${build.format})…`),
37
- },
38
- }
39
- : {}
40
- }
package/src/App.ts DELETED
@@ -1,86 +0,0 @@
1
- import { createHeadManager, router } from '@inertiajs/core'
2
- import { createElement, useEffect, useMemo, useState } from 'react'
3
- import HeadContext from './HeadContext'
4
- import PageContext from './PageContext'
5
-
6
- export default function App({
7
- children,
8
- initialPage,
9
- initialComponent,
10
- resolveComponent,
11
- titleCallback,
12
- onHeadUpdate,
13
- }) {
14
- const [current, setCurrent] = useState({
15
- component: initialComponent || null,
16
- page: initialPage,
17
- key: null,
18
- })
19
-
20
- const headManager = useMemo(() => {
21
- return createHeadManager(
22
- typeof window === 'undefined',
23
- titleCallback || ((title) => title),
24
- onHeadUpdate || (() => {}),
25
- )
26
- }, [])
27
-
28
- useEffect(() => {
29
- router.init({
30
- initialPage,
31
- resolveComponent,
32
- swapComponent: async ({ component, page, preserveState }) => {
33
- setCurrent((current) => ({
34
- component,
35
- page,
36
- key: preserveState ? current.key : Date.now(),
37
- }))
38
- },
39
- })
40
-
41
- router.on('navigate', () => headManager.forceUpdate())
42
- }, [])
43
-
44
- if (!current.component) {
45
- return createElement(
46
- HeadContext.Provider,
47
- { value: headManager },
48
- createElement(PageContext.Provider, { value: current.page }, null),
49
- )
50
- }
51
-
52
- const renderChildren =
53
- children ||
54
- (({ Component, props, key }) => {
55
- const child = createElement(Component, { key, ...props })
56
-
57
- if (typeof Component.layout === 'function') {
58
- return Component.layout(child)
59
- }
60
-
61
- if (Array.isArray(Component.layout)) {
62
- return Component.layout
63
- .concat(child)
64
- .reverse()
65
- .reduce((children, Layout) => createElement(Layout, { children, ...props }))
66
- }
67
-
68
- return child
69
- })
70
-
71
- return createElement(
72
- HeadContext.Provider,
73
- { value: headManager },
74
- createElement(
75
- PageContext.Provider,
76
- { value: current.page },
77
- renderChildren({
78
- Component: current.component,
79
- key: current.key,
80
- props: current.page.props,
81
- }),
82
- ),
83
- )
84
- }
85
-
86
- App.displayName = 'Inertia'
package/src/Head.ts DELETED
@@ -1,99 +0,0 @@
1
- import React, { FunctionComponent, useContext, useEffect, useMemo } from 'react'
2
- import HeadContext from './HeadContext'
3
-
4
- type InertiaHeadProps = {
5
- title?: string
6
- }
7
-
8
- type InertiaHead = FunctionComponent<InertiaHeadProps>
9
-
10
- const Head: InertiaHead = function ({ children, title }) {
11
- const headManager = useContext(HeadContext)
12
- const provider = useMemo(() => headManager.createProvider(), [headManager])
13
-
14
- useEffect(() => {
15
- return () => {
16
- provider.disconnect()
17
- }
18
- }, [provider])
19
-
20
- function isUnaryTag(node) {
21
- return (
22
- [
23
- 'area',
24
- 'base',
25
- 'br',
26
- 'col',
27
- 'embed',
28
- 'hr',
29
- 'img',
30
- 'input',
31
- 'keygen',
32
- 'link',
33
- 'meta',
34
- 'param',
35
- 'source',
36
- 'track',
37
- 'wbr',
38
- ].indexOf(node.type) > -1
39
- )
40
- }
41
-
42
- function renderTagStart(node) {
43
- const attrs = Object.keys(node.props).reduce((carry, name) => {
44
- if (['head-key', 'children', 'dangerouslySetInnerHTML'].includes(name)) {
45
- return carry
46
- }
47
- const value = node.props[name]
48
- if (value === '') {
49
- return carry + ` ${name}`
50
- } else {
51
- return carry + ` ${name}="${value}"`
52
- }
53
- }, '')
54
- return `<${node.type}${attrs}>`
55
- }
56
-
57
- function renderTagChildren(node) {
58
- return typeof node.props.children === 'string'
59
- ? node.props.children
60
- : node.props.children.reduce((html, child) => html + renderTag(child), '')
61
- }
62
-
63
- function renderTag(node) {
64
- let html = renderTagStart(node)
65
- if (node.props.children) {
66
- html += renderTagChildren(node)
67
- }
68
- if (node.props.dangerouslySetInnerHTML) {
69
- html += node.props.dangerouslySetInnerHTML.__html
70
- }
71
- if (!isUnaryTag(node)) {
72
- html += `</${node.type}>`
73
- }
74
- return html
75
- }
76
-
77
- function ensureNodeHasInertiaProp(node) {
78
- return React.cloneElement(node, {
79
- inertia: node.props['head-key'] !== undefined ? node.props['head-key'] : '',
80
- })
81
- }
82
-
83
- function renderNode(node) {
84
- return renderTag(ensureNodeHasInertiaProp(node))
85
- }
86
-
87
- function renderNodes(nodes) {
88
- const computed = (Array.isArray(nodes) ? nodes : [nodes]).filter((node) => node).map((node) => renderNode(node))
89
- if (title && !computed.find((tag) => tag.startsWith('<title'))) {
90
- computed.push(`<title inertia>${title}</title>`)
91
- }
92
- return computed
93
- }
94
-
95
- provider.update(renderNodes(children))
96
-
97
- return null
98
- }
99
- export default Head
@@ -1,6 +0,0 @@
1
- import { createContext } from 'react'
2
-
3
- const headContext = createContext(undefined)
4
- headContext.displayName = 'InertiaHeadContext'
5
-
6
- export default headContext
package/src/Link.ts DELETED
@@ -1,141 +0,0 @@
1
- import {
2
- FormDataConvertible,
3
- mergeDataIntoQueryString,
4
- Method,
5
- PreserveStateOption,
6
- Progress,
7
- router,
8
- shouldIntercept,
9
- } from '@inertiajs/core'
10
- import { createElement, forwardRef, useCallback } from 'react'
11
-
12
- const noop = () => undefined
13
-
14
- interface BaseInertiaLinkProps {
15
- as?: string
16
- data?: Record<string, FormDataConvertible>
17
- href: string
18
- method?: Method
19
- headers?: Record<string, string>
20
- onClick?: (event: React.MouseEvent<HTMLAnchorElement> | React.KeyboardEvent<HTMLAnchorElement>) => void
21
- preserveScroll?: PreserveStateOption
22
- preserveState?: PreserveStateOption
23
- replace?: boolean
24
- only?: string[]
25
- onCancelToken?: (cancelToken: import('axios').CancelTokenSource) => void
26
- onBefore?: () => void
27
- onStart?: () => void
28
- onProgress?: (progress: Progress) => void
29
- onFinish?: () => void
30
- onCancel?: () => void
31
- onSuccess?: () => void
32
- onError?: () => void
33
- queryStringArrayFormat?: 'indices' | 'brackets'
34
- }
35
-
36
- type InertiaLinkProps = BaseInertiaLinkProps &
37
- Omit<React.HTMLAttributes<HTMLElement>, keyof BaseInertiaLinkProps> &
38
- Omit<React.AllHTMLAttributes<HTMLElement>, keyof BaseInertiaLinkProps>
39
-
40
- type InertiaLink = React.FunctionComponent<InertiaLinkProps>
41
-
42
- const Link: InertiaLink = forwardRef<unknown, InertiaLinkProps>(
43
- (
44
- {
45
- children,
46
- as = 'a',
47
- data = {},
48
- href,
49
- method = Method.GET,
50
- preserveScroll = false,
51
- preserveState = null,
52
- replace = false,
53
- only = [],
54
- headers = {},
55
- queryStringArrayFormat = 'brackets',
56
- onClick = noop,
57
- onCancelToken = noop,
58
- onBefore = noop,
59
- onStart = noop,
60
- onProgress = noop,
61
- onFinish = noop,
62
- onCancel = noop,
63
- onSuccess = noop,
64
- onError = noop,
65
- ...props
66
- },
67
- ref,
68
- ) => {
69
- const visit = useCallback(
70
- (event) => {
71
- onClick(event)
72
-
73
- if (shouldIntercept(event)) {
74
- event.preventDefault()
75
-
76
- router.visit(href, {
77
- data,
78
- method,
79
- preserveScroll,
80
- preserveState: preserveState ?? method !== 'get',
81
- replace,
82
- only,
83
- headers,
84
- onCancelToken,
85
- onBefore,
86
- onStart,
87
- onProgress,
88
- onFinish,
89
- onCancel,
90
- onSuccess,
91
- onError,
92
- })
93
- }
94
- },
95
- [
96
- data,
97
- href,
98
- method,
99
- preserveScroll,
100
- preserveState,
101
- replace,
102
- only,
103
- headers,
104
- onClick,
105
- onCancelToken,
106
- onBefore,
107
- onStart,
108
- onProgress,
109
- onFinish,
110
- onCancel,
111
- onSuccess,
112
- onError,
113
- ],
114
- )
115
-
116
- as = as.toLowerCase()
117
- method = method.toLowerCase() as Method
118
- const [_href, _data] = mergeDataIntoQueryString(method, href || '', data, queryStringArrayFormat)
119
- href = _href
120
- data = _data
121
-
122
- if (as === 'a' && method !== 'get') {
123
- console.warn(
124
- `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>`,
125
- )
126
- }
127
-
128
- return createElement(
129
- as,
130
- {
131
- ...props,
132
- ...(as === 'a' ? { href } : {}),
133
- ref,
134
- onClick: visit,
135
- },
136
- children,
137
- )
138
- },
139
- )
140
-
141
- export default Link
@@ -1,6 +0,0 @@
1
- import { createContext } from 'react'
2
-
3
- const pageContext = createContext(undefined)
4
- pageContext.displayName = 'InertiaPageContext'
5
-
6
- export default pageContext
@@ -1,119 +0,0 @@
1
- import { Page, PageProps, PageResolver, setupProgress } from '@inertiajs/core'
2
- import { ComponentType, createElement, FunctionComponent, Key, ReactElement, ReactNode } from 'react'
3
- import { renderToString } from 'react-dom/server'
4
- import App from './App'
5
-
6
- type ReactInstance = ReactElement
7
- type ReactComponent = ReactNode
8
-
9
- type HeadManagerOnUpdate = (elements: string[]) => void // TODO: When shipped, replace with: Inertia.HeadManagerOnUpdate
10
- type HeadManagerTitleCallback = (title: string) => string // TODO: When shipped, replace with: Inertia.HeadManagerTitleCallback
11
-
12
- type AppType<SharedProps = PageProps> = FunctionComponent<
13
- {
14
- children?: (props: { Component: ComponentType; key: Key; props: Page<SharedProps>['props'] }) => ReactNode
15
- } & SetupOptions<unknown, SharedProps>['props']
16
- >
17
-
18
- export type SetupOptions<ElementType, SharedProps> = {
19
- el: ElementType
20
- App: AppType
21
- props: {
22
- initialPage: Page<SharedProps>
23
- initialComponent: ReactComponent
24
- resolveComponent: PageResolver
25
- titleCallback?: HeadManagerTitleCallback
26
- onHeadUpdate?: HeadManagerOnUpdate
27
- }
28
- }
29
-
30
- type BaseInertiaAppOptions = {
31
- title?: HeadManagerTitleCallback
32
- resolve: PageResolver
33
- }
34
-
35
- type CreateInertiaAppSetupReturnType = ReactInstance | void
36
- type InertiaAppOptionsForCSR<SharedProps> = BaseInertiaAppOptions & {
37
- id?: string
38
- page?: Page | string
39
- render?: undefined
40
- progress?:
41
- | false
42
- | {
43
- delay?: number
44
- color?: string
45
- includeCSS?: boolean
46
- showSpinner?: boolean
47
- }
48
- setup(options: SetupOptions<HTMLElement, SharedProps>): CreateInertiaAppSetupReturnType
49
- }
50
-
51
- type CreateInertiaAppSSRContent = { head: string[]; body: string }
52
- type InertiaAppOptionsForSSR<SharedProps> = BaseInertiaAppOptions & {
53
- id?: undefined
54
- page: Page | string
55
- render: typeof renderToString
56
- progress: undefined
57
- setup(options: SetupOptions<null, SharedProps>): ReactInstance
58
- }
59
-
60
- export default async function createInertiaApp<SharedProps = PageProps>(
61
- options: InertiaAppOptionsForCSR<SharedProps>,
62
- ): Promise<CreateInertiaAppSetupReturnType>
63
- export default async function createInertiaApp<SharedProps = PageProps>(
64
- options: InertiaAppOptionsForSSR<SharedProps>,
65
- ): Promise<CreateInertiaAppSSRContent>
66
- export default async function createInertiaApp<SharedProps = PageProps>({
67
- id = 'app',
68
- resolve,
69
- setup,
70
- title,
71
- progress = {},
72
- page,
73
- render,
74
- }: InertiaAppOptionsForCSR<SharedProps> | InertiaAppOptionsForSSR<SharedProps>): Promise<
75
- CreateInertiaAppSetupReturnType | CreateInertiaAppSSRContent
76
- > {
77
- const isServer = typeof window === 'undefined'
78
- const el = isServer ? null : document.getElementById(id)
79
- const initialPage = page || JSON.parse(el.dataset.page)
80
- // @ts-expect-error
81
- const resolveComponent = (name) => Promise.resolve(resolve(name)).then((module) => module.default || module)
82
-
83
- let head = []
84
-
85
- const reactApp = await resolveComponent(initialPage.component).then((initialComponent) => {
86
- return setup({
87
- // @ts-expect-error
88
- el,
89
- App,
90
- props: {
91
- initialPage,
92
- initialComponent,
93
- resolveComponent,
94
- titleCallback: title,
95
- onHeadUpdate: isServer ? (elements) => (head = elements) : null,
96
- },
97
- })
98
- })
99
-
100
- if (!isServer && progress) {
101
- setupProgress(progress)
102
- }
103
-
104
- if (isServer) {
105
- const body = await render(
106
- createElement(
107
- 'div',
108
- {
109
- id,
110
- 'data-page': JSON.stringify(initialPage),
111
- },
112
- // @ts-expect-error
113
- reactApp,
114
- ),
115
- )
116
-
117
- return { head, body }
118
- }
119
- }
package/src/index.ts DELETED
@@ -1,9 +0,0 @@
1
- import { router as Router } from '@inertiajs/core'
2
-
3
- export const router = Router
4
- export { default as createInertiaApp } from './createInertiaApp'
5
- export { default as Head } from './Head'
6
- export { default as Link } from './Link'
7
- export { default as useForm } from './useForm'
8
- export { default as usePage } from './usePage'
9
- export { default as useRemember } from './useRemember'
package/src/server.ts DELETED
@@ -1 +0,0 @@
1
- export { default as default } from '@inertiajs/core/server'
package/src/useForm.ts DELETED
@@ -1,263 +0,0 @@
1
- import { Method, Progress, router, VisitOptions } from '@inertiajs/core'
2
- import isEqual from 'lodash.isequal'
3
- import { useCallback, useEffect, useRef, useState } from 'react'
4
- import useRemember from './useRemember'
5
-
6
- type setDataByObject<TForm> = (data: TForm) => void
7
- type setDataByMethod<TForm> = (data: (previousData: TForm) => TForm) => void
8
- type setDataByKeyValuePair<TForm> = <K extends keyof TForm>(key: K, value: TForm[K]) => void
9
-
10
- export interface InertiaFormProps<TForm extends Record<string, unknown>> {
11
- data: TForm
12
- isDirty: boolean
13
- errors: Partial<Record<keyof TForm, string>>
14
- hasErrors: boolean
15
- processing: boolean
16
- progress: Progress | null
17
- wasSuccessful: boolean
18
- recentlySuccessful: boolean
19
- setData: setDataByObject<TForm> & setDataByMethod<TForm> & setDataByKeyValuePair<TForm>
20
- transform: (callback: (data: TForm) => TForm) => void
21
- setDefaults(): void
22
- setDefaults(field: keyof TForm, value: string): void
23
- setDefaults(fields: Record<keyof TForm, string>): void
24
- reset: (...fields: (keyof TForm)[]) => void
25
- clearErrors: (...fields: (keyof TForm)[]) => void
26
- setError(field: keyof TForm, value: string): void
27
- setError(errors: Record<keyof TForm, string>): void
28
- submit: (method: Method, url: string, options?: VisitOptions) => void
29
- get: (url: string, options?: VisitOptions) => void
30
- patch: (url: string, options?: VisitOptions) => void
31
- post: (url: string, options?: VisitOptions) => void
32
- put: (url: string, options?: VisitOptions) => void
33
- delete: (url: string, options?: VisitOptions) => void
34
- cancel: () => void
35
- }
36
- export default function useForm<TForm extends Record<string, unknown>>(initialValues?: TForm): InertiaFormProps<TForm>
37
- export default function useForm<TForm extends Record<string, unknown>>(
38
- rememberKey: string,
39
- initialValues?: TForm,
40
- ): InertiaFormProps<TForm>
41
- export default function useForm<TForm extends Record<string, unknown>>(
42
- rememberKeyOrInitialValues?: string | TForm,
43
- maybeInitialValues?: TForm,
44
- ): InertiaFormProps<TForm> {
45
- const isMounted = useRef(null)
46
- const rememberKey = typeof rememberKeyOrInitialValues === 'string' ? rememberKeyOrInitialValues : null
47
- const [defaults, setDefaults] = useState(
48
- (typeof rememberKeyOrInitialValues === 'string' ? maybeInitialValues : rememberKeyOrInitialValues) || ({} as TForm),
49
- )
50
- const cancelToken = useRef(null)
51
- const recentlySuccessfulTimeoutId = useRef(null)
52
- const [data, setData] = rememberKey ? useRemember(defaults, `${rememberKey}:data`) : useState(defaults)
53
- const [errors, setErrors] = rememberKey
54
- ? useRemember({} as Partial<Record<keyof TForm, string>>, `${rememberKey}:errors`)
55
- : useState({} as Partial<Record<keyof TForm, string>>)
56
- const [hasErrors, setHasErrors] = useState(false)
57
- const [processing, setProcessing] = useState(false)
58
- const [progress, setProgress] = useState(null)
59
- const [wasSuccessful, setWasSuccessful] = useState(false)
60
- const [recentlySuccessful, setRecentlySuccessful] = useState(false)
61
- let transform = (data) => data
62
-
63
- useEffect(() => {
64
- isMounted.current = true
65
- return () => {
66
- isMounted.current = false
67
- }
68
- }, [])
69
-
70
- const submit = useCallback(
71
- (method, url, options = {}) => {
72
- const _options = {
73
- ...options,
74
- onCancelToken: (token) => {
75
- cancelToken.current = token
76
-
77
- if (options.onCancelToken) {
78
- return options.onCancelToken(token)
79
- }
80
- },
81
- onBefore: (visit) => {
82
- setWasSuccessful(false)
83
- setRecentlySuccessful(false)
84
- clearTimeout(recentlySuccessfulTimeoutId.current)
85
-
86
- if (options.onBefore) {
87
- return options.onBefore(visit)
88
- }
89
- },
90
- onStart: (visit) => {
91
- setProcessing(true)
92
-
93
- if (options.onStart) {
94
- return options.onStart(visit)
95
- }
96
- },
97
- onProgress: (event) => {
98
- setProgress(event)
99
-
100
- if (options.onProgress) {
101
- return options.onProgress(event)
102
- }
103
- },
104
- onSuccess: (page) => {
105
- if (isMounted.current) {
106
- setProcessing(false)
107
- setProgress(null)
108
- setErrors({})
109
- setHasErrors(false)
110
- setWasSuccessful(true)
111
- setRecentlySuccessful(true)
112
- recentlySuccessfulTimeoutId.current = setTimeout(() => {
113
- if (isMounted.current) {
114
- setRecentlySuccessful(false)
115
- }
116
- }, 2000)
117
- }
118
-
119
- if (options.onSuccess) {
120
- return options.onSuccess(page)
121
- }
122
- },
123
- onError: (errors) => {
124
- if (isMounted.current) {
125
- setProcessing(false)
126
- setProgress(null)
127
- setErrors(errors)
128
- setHasErrors(true)
129
- }
130
-
131
- if (options.onError) {
132
- return options.onError(errors)
133
- }
134
- },
135
- onCancel: () => {
136
- if (isMounted.current) {
137
- setProcessing(false)
138
- setProgress(null)
139
- }
140
-
141
- if (options.onCancel) {
142
- return options.onCancel()
143
- }
144
- },
145
- onFinish: () => {
146
- if (isMounted.current) {
147
- setProcessing(false)
148
- setProgress(null)
149
- }
150
-
151
- cancelToken.current = null
152
-
153
- if (options.onFinish) {
154
- return options.onFinish()
155
- }
156
- },
157
- }
158
-
159
- if (method === 'delete') {
160
- router.delete(url, { ..._options, data: transform(data) })
161
- } else {
162
- router[method](url, transform(data), _options)
163
- }
164
- },
165
- [data, setErrors],
166
- )
167
-
168
- return {
169
- data,
170
- setData(keyOrData: keyof TForm | Function | TForm, maybeValue?: TForm[keyof TForm]) {
171
- if (typeof keyOrData === 'string') {
172
- setData({ ...data, [keyOrData]: maybeValue })
173
- } else if (typeof keyOrData === 'function') {
174
- setData((data) => keyOrData(data))
175
- } else {
176
- setData(keyOrData as TForm)
177
- }
178
- },
179
- isDirty: !isEqual(data, defaults),
180
- errors,
181
- hasErrors,
182
- processing,
183
- progress,
184
- wasSuccessful,
185
- recentlySuccessful,
186
- transform(callback) {
187
- transform = callback
188
- },
189
- setDefaults(fieldOrFields?: keyof TForm | Record<keyof TForm, string>, maybeValue?: string) {
190
- if (typeof fieldOrFields === 'undefined') {
191
- setDefaults(() => data)
192
- } else {
193
- setDefaults((defaults) => ({
194
- ...defaults,
195
- ...(typeof fieldOrFields === 'string' ? { [fieldOrFields]: maybeValue } : (fieldOrFields as TForm)),
196
- }))
197
- }
198
- },
199
- reset(...fields) {
200
- if (fields.length === 0) {
201
- setData(defaults)
202
- } else {
203
- setData(
204
- (Object.keys(defaults) as Array<keyof TForm>)
205
- .filter((key) => fields.includes(key))
206
- .reduce(
207
- (carry, key) => {
208
- carry[key] = defaults[key]
209
- return carry
210
- },
211
- { ...data },
212
- ),
213
- )
214
- }
215
- },
216
- setError(fieldOrFields: keyof TForm | Record<keyof TForm, string>, maybeValue?: string) {
217
- setErrors((errors) => {
218
- const newErrors = {
219
- ...errors,
220
- ...(typeof fieldOrFields === 'string'
221
- ? { [fieldOrFields]: maybeValue }
222
- : (fieldOrFields as Record<keyof TForm, string>)),
223
- }
224
- setHasErrors(Object.keys(newErrors).length > 0)
225
- return newErrors
226
- })
227
- },
228
- clearErrors(...fields) {
229
- setErrors((errors) => {
230
- const newErrors = (Object.keys(errors) as Array<keyof TForm>).reduce(
231
- (carry, field) => ({
232
- ...carry,
233
- ...(fields.length > 0 && !fields.includes(field) ? { [field]: errors[field] } : {}),
234
- }),
235
- {},
236
- )
237
- setHasErrors(Object.keys(newErrors).length > 0)
238
- return newErrors
239
- })
240
- },
241
- submit,
242
- get(url, options) {
243
- submit('get', url, options)
244
- },
245
- post(url, options) {
246
- submit('post', url, options)
247
- },
248
- put(url, options) {
249
- submit('put', url, options)
250
- },
251
- patch(url, options) {
252
- submit('patch', url, options)
253
- },
254
- delete(url, options) {
255
- submit('delete', url, options)
256
- },
257
- cancel() {
258
- if (cancelToken.current) {
259
- cancelToken.current.cancel()
260
- }
261
- },
262
- }
263
- }
package/src/usePage.ts DELETED
@@ -1,13 +0,0 @@
1
- import { Page } from '@inertiajs/core'
2
- import { useContext } from 'react'
3
- import PageContext from './PageContext'
4
-
5
- export default function usePage(): Page {
6
- const page = useContext(PageContext)
7
-
8
- if (!page) {
9
- throw new Error('usePage must be used within the Inertia component')
10
- }
11
-
12
- return page
13
- }
@@ -1,27 +0,0 @@
1
- import { router } from '@inertiajs/core'
2
- import { Dispatch, SetStateAction, useEffect, useState } from 'react'
3
-
4
- export default function useRemember<State>(
5
- initialState: State,
6
- key?: string,
7
- ): [State, Dispatch<SetStateAction<State>>] {
8
- const [state, setState] = useState(() => {
9
- const restored = router.restore(key) as State
10
-
11
- return restored !== undefined ? restored : initialState
12
- })
13
-
14
- useEffect(() => {
15
- router.remember(state, key)
16
- }, [state, key])
17
-
18
- return [state, setState]
19
- }
20
-
21
- /** @deprecated use `useRemember` instead */
22
- export function useRememberedState<State>(initialState: State, key?: string): [State, Dispatch<SetStateAction<State>>] {
23
- console.warn(
24
- 'The "useRememberedState" hook has been deprecated and will be removed in a future release. Use "useRemember" instead.',
25
- )
26
- return useRemember(initialState, key)
27
- }
package/tsconfig.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "include": ["src/index.ts"],
3
- "compilerOptions": {
4
- "rootDir": "src",
5
- "noEmitOnError": true,
6
-
7
- "lib": ["DOM", "DOM.Iterable", "ES2020"],
8
- "target": "ES2020",
9
- "types": ["node"],
10
-
11
- "declaration": true,
12
- "declarationDir": "types",
13
-
14
- "module": "ES2020",
15
- "moduleResolution": "Node",
16
- "resolveJsonModule": true,
17
- "allowSyntheticDefaultImports": true,
18
-
19
- "noImplicitThis": false,
20
- "noUnusedLocals": true,
21
- "noUnusedParameters": true,
22
- "preserveConstEnums": true,
23
- "removeComments": true,
24
- "typeRoots": ["./node_modules/@types"]
25
- // "strict": true
26
- }
27
- }