@void/react 0.27.0 → 1.0.3
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/index.d.mts +103 -2
- package/dist/index.mjs +460 -1
- package/dist/plugin.d.mts +2 -1
- package/dist/plugin.mjs +177 -197
- package/dist/runtime/pages-client.d.mts +2 -1
- package/dist/runtime/pages-server.d.mts +2 -1
- package/dist/runtime/pages-server.mjs +12 -1
- package/package.json +6 -6
- package/dist/index-D5M3zrVB.d.mts +0 -103
- package/dist/runtime/index.d.mts +0 -2
- package/dist/runtime/index.mjs +0 -4
- package/dist/runtime--GesOVur.mjs +0 -468
|
@@ -1,468 +0,0 @@
|
|
|
1
|
-
import { a as SharedContext, i as RouterContext, n as NavigationContext, r as ParamsContext } from "./context-B0GL7p5m.mjs";
|
|
2
|
-
import "./action-4EvQppia.mjs";
|
|
3
|
-
import { useActionState, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { VoidActionError, categorizeActionError, formErrorMessage, formRetryMessage, formSubmissionBlocked, getValidationErrors, interpolateRouteParams, isAbortError, isEqualFormValue, isModifiedEvent, mergeDataIntoHref, scheduleFormRetry, ssrProxy, submitAction } from "void/pages-client";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
//#region src/runtime/form.tsx
|
|
7
|
-
function Form({ form, method = "post", renderError, children, ...props }) {
|
|
8
|
-
const [now, setNow] = useState(Date.now);
|
|
9
|
-
useEffect(() => scheduleFormRetry(form.error, () => setNow(Date.now())), [form.error]);
|
|
10
|
-
const message = formErrorMessage(form);
|
|
11
|
-
const retry = formRetryMessage(form.error);
|
|
12
|
-
const blocked = formSubmissionBlocked(form, now);
|
|
13
|
-
return /* @__PURE__ */ jsxs("form", {
|
|
14
|
-
...props,
|
|
15
|
-
action: form[method],
|
|
16
|
-
"aria-busy": form.pending,
|
|
17
|
-
onSubmit: (event) => {
|
|
18
|
-
if (blocked) event.preventDefault();
|
|
19
|
-
},
|
|
20
|
-
children: [message && /* @__PURE__ */ jsxs("div", {
|
|
21
|
-
role: "alert",
|
|
22
|
-
"data-void-form-error": true,
|
|
23
|
-
children: [form.error && renderError ? renderError(form.error) : message, retry && /* @__PURE__ */ jsx("p", { children: retry })]
|
|
24
|
-
}), children]
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
//#endregion
|
|
28
|
-
//#region src/runtime/link.tsx
|
|
29
|
-
function hasPrefetch(prefetch) {
|
|
30
|
-
return prefetch !== false;
|
|
31
|
-
}
|
|
32
|
-
function Link({ href, method = "GET", data, preserveScroll = false, preserveState = false, replace = false, reloadDocument = false, viewTransition, prefetch: prefetchProp = false, cacheFor, onNavigate, children, style, onClick: onClickProp, onMouseEnter: onMouseEnterProp, onMouseLeave: onMouseLeaveProp, onFocus: onFocusProp, onMouseDown: onMouseDownProp, onTouchStart: onTouchStartProp, ...rest }) {
|
|
33
|
-
const router = useContext(RouterContext);
|
|
34
|
-
const elementRef = useRef(null);
|
|
35
|
-
const hoverTimerRef = useRef(null);
|
|
36
|
-
const normalizedMethod = useMemo(() => method.toUpperCase(), [method]);
|
|
37
|
-
const isGet = normalizedMethod === "GET";
|
|
38
|
-
const hrefWithData = useMemo(() => isGet ? mergeDataIntoHref(href, data) : href, [
|
|
39
|
-
data,
|
|
40
|
-
href,
|
|
41
|
-
isGet
|
|
42
|
-
]);
|
|
43
|
-
const strategies = useMemo(() => {
|
|
44
|
-
if (prefetchProp === false || reloadDocument) return [];
|
|
45
|
-
if (prefetchProp === true) return ["hover"];
|
|
46
|
-
if (typeof prefetchProp === "string") return [prefetchProp];
|
|
47
|
-
return prefetchProp;
|
|
48
|
-
}, [prefetchProp, reloadDocument]);
|
|
49
|
-
const hoverDelay = router?._hoverDelay ?? 75;
|
|
50
|
-
if (hasPrefetch(prefetchProp) && !isGet) throw new Error("Link: prefetch only supports GET links. Remove `prefetch` or use method=\"GET\".");
|
|
51
|
-
if (reloadDocument && !isGet) throw new Error("Link: reloadDocument only supports GET links.");
|
|
52
|
-
const doPrefetch = useCallback(() => {
|
|
53
|
-
if (!router?.prefetch) return;
|
|
54
|
-
const current = window.location.pathname + window.location.search;
|
|
55
|
-
if (hrefWithData === current) return;
|
|
56
|
-
const options = {};
|
|
57
|
-
if (cacheFor !== void 0) options.cacheFor = cacheFor;
|
|
58
|
-
if (normalizedMethod) options.method = normalizedMethod;
|
|
59
|
-
router.prefetch(hrefWithData, options);
|
|
60
|
-
}, [
|
|
61
|
-
cacheFor,
|
|
62
|
-
hrefWithData,
|
|
63
|
-
normalizedMethod,
|
|
64
|
-
router
|
|
65
|
-
]);
|
|
66
|
-
const shouldHandleClick = useCallback((event) => {
|
|
67
|
-
if (reloadDocument || !router || event.defaultPrevented || isModifiedEvent(event)) return false;
|
|
68
|
-
if (event.currentTarget.hasAttribute("download")) return false;
|
|
69
|
-
if (new URL(hrefWithData, window.location.origin).origin !== window.location.origin) return false;
|
|
70
|
-
return true;
|
|
71
|
-
}, [
|
|
72
|
-
hrefWithData,
|
|
73
|
-
reloadDocument,
|
|
74
|
-
router
|
|
75
|
-
]);
|
|
76
|
-
const onClick = useCallback((event) => {
|
|
77
|
-
onClickProp?.(event);
|
|
78
|
-
if (!shouldHandleClick(event)) return;
|
|
79
|
-
let navigatePrevented = false;
|
|
80
|
-
onNavigate?.({ preventDefault() {
|
|
81
|
-
navigatePrevented = true;
|
|
82
|
-
} });
|
|
83
|
-
if (navigatePrevented) {
|
|
84
|
-
event.preventDefault();
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
event.preventDefault();
|
|
88
|
-
router?.visit(hrefWithData, {
|
|
89
|
-
method: normalizedMethod,
|
|
90
|
-
data: isGet ? void 0 : data,
|
|
91
|
-
preserveScroll,
|
|
92
|
-
preserveState,
|
|
93
|
-
replace,
|
|
94
|
-
viewTransition
|
|
95
|
-
});
|
|
96
|
-
}, [
|
|
97
|
-
data,
|
|
98
|
-
hrefWithData,
|
|
99
|
-
isGet,
|
|
100
|
-
normalizedMethod,
|
|
101
|
-
onClickProp,
|
|
102
|
-
onNavigate,
|
|
103
|
-
preserveScroll,
|
|
104
|
-
preserveState,
|
|
105
|
-
replace,
|
|
106
|
-
router,
|
|
107
|
-
shouldHandleClick,
|
|
108
|
-
viewTransition
|
|
109
|
-
]);
|
|
110
|
-
const onMouseEnter = useCallback((event) => {
|
|
111
|
-
onMouseEnterProp?.(event);
|
|
112
|
-
if (event.defaultPrevented) return;
|
|
113
|
-
if (hoverTimerRef.current) clearTimeout(hoverTimerRef.current);
|
|
114
|
-
hoverTimerRef.current = setTimeout(doPrefetch, hoverDelay);
|
|
115
|
-
}, [
|
|
116
|
-
doPrefetch,
|
|
117
|
-
hoverDelay,
|
|
118
|
-
onMouseEnterProp
|
|
119
|
-
]);
|
|
120
|
-
const onMouseLeave = useCallback((event) => {
|
|
121
|
-
onMouseLeaveProp?.(event);
|
|
122
|
-
if (hoverTimerRef.current) {
|
|
123
|
-
clearTimeout(hoverTimerRef.current);
|
|
124
|
-
hoverTimerRef.current = null;
|
|
125
|
-
}
|
|
126
|
-
}, [onMouseLeaveProp]);
|
|
127
|
-
const onFocus = useCallback((event) => {
|
|
128
|
-
onFocusProp?.(event);
|
|
129
|
-
if (!event.defaultPrevented) doPrefetch();
|
|
130
|
-
}, [doPrefetch, onFocusProp]);
|
|
131
|
-
const onMouseDown = useCallback((event) => {
|
|
132
|
-
onMouseDownProp?.(event);
|
|
133
|
-
if (!event.defaultPrevented) doPrefetch();
|
|
134
|
-
}, [doPrefetch, onMouseDownProp]);
|
|
135
|
-
const onTouchStart = useCallback((event) => {
|
|
136
|
-
onTouchStartProp?.(event);
|
|
137
|
-
if (!event.defaultPrevented) doPrefetch();
|
|
138
|
-
}, [doPrefetch, onTouchStartProp]);
|
|
139
|
-
useEffect(() => {
|
|
140
|
-
if (strategies.length === 0) return;
|
|
141
|
-
if (strategies.includes("mount")) doPrefetch();
|
|
142
|
-
let observer = null;
|
|
143
|
-
if (strategies.includes("visible") && elementRef.current) {
|
|
144
|
-
observer = new IntersectionObserver((entries) => {
|
|
145
|
-
if (entries.some((e) => e.isIntersecting)) {
|
|
146
|
-
doPrefetch();
|
|
147
|
-
observer?.disconnect();
|
|
148
|
-
observer = null;
|
|
149
|
-
}
|
|
150
|
-
}, { rootMargin: "0px" });
|
|
151
|
-
observer.observe(elementRef.current);
|
|
152
|
-
}
|
|
153
|
-
return () => {
|
|
154
|
-
if (hoverTimerRef.current) {
|
|
155
|
-
clearTimeout(hoverTimerRef.current);
|
|
156
|
-
hoverTimerRef.current = null;
|
|
157
|
-
}
|
|
158
|
-
if (observer) observer.disconnect();
|
|
159
|
-
};
|
|
160
|
-
}, [doPrefetch, strategies]);
|
|
161
|
-
const eventHandlers = useMemo(() => {
|
|
162
|
-
const handlers = {
|
|
163
|
-
onClick,
|
|
164
|
-
onFocus: onFocusProp,
|
|
165
|
-
onMouseDown: onMouseDownProp,
|
|
166
|
-
onMouseEnter: onMouseEnterProp,
|
|
167
|
-
onMouseLeave: onMouseLeaveProp,
|
|
168
|
-
onTouchStart: onTouchStartProp
|
|
169
|
-
};
|
|
170
|
-
if (strategies.includes("hover")) {
|
|
171
|
-
handlers.onMouseEnter = onMouseEnter;
|
|
172
|
-
handlers.onMouseLeave = onMouseLeave;
|
|
173
|
-
handlers.onFocus = onFocus;
|
|
174
|
-
handlers.onTouchStart = onTouchStart;
|
|
175
|
-
}
|
|
176
|
-
if (strategies.includes("click")) {
|
|
177
|
-
handlers.onMouseDown = onMouseDown;
|
|
178
|
-
handlers.onTouchStart = onTouchStart;
|
|
179
|
-
}
|
|
180
|
-
return handlers;
|
|
181
|
-
}, [
|
|
182
|
-
onClick,
|
|
183
|
-
onFocus,
|
|
184
|
-
onFocusProp,
|
|
185
|
-
onMouseDown,
|
|
186
|
-
onMouseDownProp,
|
|
187
|
-
onMouseEnter,
|
|
188
|
-
onMouseEnterProp,
|
|
189
|
-
onMouseLeave,
|
|
190
|
-
onMouseLeaveProp,
|
|
191
|
-
onTouchStart,
|
|
192
|
-
onTouchStartProp,
|
|
193
|
-
strategies
|
|
194
|
-
]);
|
|
195
|
-
const resolvedStyle = useMemo(() => ({
|
|
196
|
-
touchAction: "manipulation",
|
|
197
|
-
...style
|
|
198
|
-
}), [style]);
|
|
199
|
-
if (isGet) return /* @__PURE__ */ jsx("a", {
|
|
200
|
-
ref: elementRef,
|
|
201
|
-
href: hrefWithData,
|
|
202
|
-
style: resolvedStyle,
|
|
203
|
-
...rest,
|
|
204
|
-
...eventHandlers,
|
|
205
|
-
children
|
|
206
|
-
});
|
|
207
|
-
return /* @__PURE__ */ jsx("button", {
|
|
208
|
-
ref: elementRef,
|
|
209
|
-
type: "button",
|
|
210
|
-
style: resolvedStyle,
|
|
211
|
-
...rest,
|
|
212
|
-
...eventHandlers,
|
|
213
|
-
children
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
//#endregion
|
|
217
|
-
//#region src/runtime/use-router.ts
|
|
218
|
-
function useRouter() {
|
|
219
|
-
return useContext(RouterContext) ?? ssrProxy;
|
|
220
|
-
}
|
|
221
|
-
//#endregion
|
|
222
|
-
//#region src/runtime/use-params.ts
|
|
223
|
-
function useParams() {
|
|
224
|
-
const params = useContext(ParamsContext);
|
|
225
|
-
if (params === null) throw new Error("useParams(): must be used inside a Void page.");
|
|
226
|
-
return params;
|
|
227
|
-
}
|
|
228
|
-
//#endregion
|
|
229
|
-
//#region src/runtime/use-shared.ts
|
|
230
|
-
function useShared() {
|
|
231
|
-
const shared = useContext(SharedContext);
|
|
232
|
-
if (!shared) throw new Error("useShared(): must be used inside a Void page.");
|
|
233
|
-
return shared;
|
|
234
|
-
}
|
|
235
|
-
//#endregion
|
|
236
|
-
//#region src/runtime/use-form.ts
|
|
237
|
-
function useForm(url, defaults, options) {
|
|
238
|
-
const router = useContext(RouterContext);
|
|
239
|
-
const [data, setDataState] = useState(() => ({ ...defaults }));
|
|
240
|
-
const [defaultsState, setDefaultsState] = useState(() => ({ ...defaults }));
|
|
241
|
-
const [errors, setErrors] = useState({});
|
|
242
|
-
const [error, setError] = useState(null);
|
|
243
|
-
const [wasSuccessful, setWasSuccessful] = useState(false);
|
|
244
|
-
const [recentlySuccessful, setRecentlySuccessful] = useState(false);
|
|
245
|
-
const defaultsRef = useRef(defaultsState);
|
|
246
|
-
const dataRef = useRef(data);
|
|
247
|
-
const successTimeoutRef = useRef(null);
|
|
248
|
-
const hasChanges = useMemo(() => {
|
|
249
|
-
return Object.keys(defaultsState).some((key) => !isEqualFormValue(data[key], defaultsState[key]));
|
|
250
|
-
}, [data, defaultsState]);
|
|
251
|
-
const setData = useCallback((field, value) => {
|
|
252
|
-
dataRef.current = {
|
|
253
|
-
...dataRef.current,
|
|
254
|
-
[field]: value
|
|
255
|
-
};
|
|
256
|
-
setDataState(dataRef.current);
|
|
257
|
-
}, []);
|
|
258
|
-
const reset = useCallback((...fields) => {
|
|
259
|
-
if (fields.length === 0) dataRef.current = { ...defaultsRef.current };
|
|
260
|
-
else {
|
|
261
|
-
const next = { ...dataRef.current };
|
|
262
|
-
for (const field of fields) next[field] = defaultsRef.current[field];
|
|
263
|
-
dataRef.current = next;
|
|
264
|
-
}
|
|
265
|
-
setDataState(dataRef.current);
|
|
266
|
-
}, []);
|
|
267
|
-
const clearErrors = useCallback((...fields) => {
|
|
268
|
-
if (fields.length === 0) setErrors({});
|
|
269
|
-
else setErrors((prev) => {
|
|
270
|
-
const next = { ...prev };
|
|
271
|
-
for (const field of fields) delete next[field];
|
|
272
|
-
return next;
|
|
273
|
-
});
|
|
274
|
-
}, []);
|
|
275
|
-
const clearError = useCallback(() => {
|
|
276
|
-
setError(null);
|
|
277
|
-
}, []);
|
|
278
|
-
const [, dispatchAction, pending] = useActionState(async (previousSuccessVersion, payload) => {
|
|
279
|
-
if (!router) throw new Error("useForm(): requires the Void Router.");
|
|
280
|
-
const method = payload instanceof FormData ? "POST" : payload.method;
|
|
281
|
-
setWasSuccessful(false);
|
|
282
|
-
setRecentlySuccessful(false);
|
|
283
|
-
if (successTimeoutRef.current) {
|
|
284
|
-
clearTimeout(successTimeoutRef.current);
|
|
285
|
-
successTimeoutRef.current = null;
|
|
286
|
-
}
|
|
287
|
-
setErrors({});
|
|
288
|
-
setError(null);
|
|
289
|
-
let result;
|
|
290
|
-
try {
|
|
291
|
-
result = await submitAction(router, interpolateRouteParams(url, options?.params), {
|
|
292
|
-
method,
|
|
293
|
-
data: { ...dataRef.current },
|
|
294
|
-
_resolveOnShell: true
|
|
295
|
-
});
|
|
296
|
-
} catch (submitError) {
|
|
297
|
-
if (isAbortError(submitError)) return previousSuccessVersion;
|
|
298
|
-
throw submitError;
|
|
299
|
-
}
|
|
300
|
-
if (!result.ok) {
|
|
301
|
-
const validationErrors = getValidationErrors(result.error.body);
|
|
302
|
-
if (validationErrors) setErrors(validationErrors);
|
|
303
|
-
else setError(result.error);
|
|
304
|
-
return previousSuccessVersion;
|
|
305
|
-
}
|
|
306
|
-
const nextDefaults = { ...dataRef.current };
|
|
307
|
-
defaultsRef.current = nextDefaults;
|
|
308
|
-
setDefaultsState(nextDefaults);
|
|
309
|
-
setWasSuccessful(true);
|
|
310
|
-
setRecentlySuccessful(true);
|
|
311
|
-
successTimeoutRef.current = setTimeout(() => {
|
|
312
|
-
setRecentlySuccessful(false);
|
|
313
|
-
successTimeoutRef.current = null;
|
|
314
|
-
}, 2e3);
|
|
315
|
-
return previousSuccessVersion + 1;
|
|
316
|
-
}, 0);
|
|
317
|
-
useEffect(() => {
|
|
318
|
-
return () => {
|
|
319
|
-
if (successTimeoutRef.current) {
|
|
320
|
-
clearTimeout(successTimeoutRef.current);
|
|
321
|
-
successTimeoutRef.current = null;
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
}, []);
|
|
325
|
-
const dispatchMethodAction = useCallback((method) => (_formData) => {
|
|
326
|
-
dispatchAction({ method });
|
|
327
|
-
}, [dispatchAction]);
|
|
328
|
-
return {
|
|
329
|
-
data,
|
|
330
|
-
setData,
|
|
331
|
-
errors,
|
|
332
|
-
error,
|
|
333
|
-
pending,
|
|
334
|
-
hasChanges,
|
|
335
|
-
wasSuccessful,
|
|
336
|
-
recentlySuccessful,
|
|
337
|
-
post: dispatchAction,
|
|
338
|
-
put: useMemo(() => dispatchMethodAction("PUT"), [dispatchMethodAction]),
|
|
339
|
-
patch: useMemo(() => dispatchMethodAction("PATCH"), [dispatchMethodAction]),
|
|
340
|
-
delete: useMemo(() => dispatchMethodAction("DELETE"), [dispatchMethodAction]),
|
|
341
|
-
reset,
|
|
342
|
-
clearErrors,
|
|
343
|
-
clearError
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
//#endregion
|
|
347
|
-
//#region src/runtime/use-navigation.ts
|
|
348
|
-
function useNavigation() {
|
|
349
|
-
return useContext(NavigationContext);
|
|
350
|
-
}
|
|
351
|
-
//#endregion
|
|
352
|
-
//#region src/runtime/use-island-form.ts
|
|
353
|
-
async function readActionErrorBody(response) {
|
|
354
|
-
const contentType = response.headers.get("content-type") || "";
|
|
355
|
-
try {
|
|
356
|
-
if (contentType.includes("application/json")) return await response.json();
|
|
357
|
-
return await response.text() || null;
|
|
358
|
-
} catch {
|
|
359
|
-
return null;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Form hook for island pages. Uses fetch + page reload instead of the
|
|
364
|
-
* Void Router (which is not available in island mode).
|
|
365
|
-
*/
|
|
366
|
-
function useIslandForm(defaults) {
|
|
367
|
-
const [data, setDataState] = useState(() => ({ ...defaults }));
|
|
368
|
-
const [defaultsState, setDefaultsState] = useState(() => ({ ...defaults }));
|
|
369
|
-
const [errors, setErrors] = useState({});
|
|
370
|
-
const [error, setError] = useState(null);
|
|
371
|
-
const [pending, setPending] = useState(false);
|
|
372
|
-
const [wasSuccessful, setWasSuccessful] = useState(false);
|
|
373
|
-
const [recentlySuccessful, setRecentlySuccessful] = useState(false);
|
|
374
|
-
const defaultsRef = useRef(defaultsState);
|
|
375
|
-
const successTimeoutRef = useRef(null);
|
|
376
|
-
const hasChanges = useMemo(() => {
|
|
377
|
-
return Object.keys(defaultsState).some((key) => !isEqualFormValue(data[key], defaultsState[key]));
|
|
378
|
-
}, [data, defaultsState]);
|
|
379
|
-
const setData = useCallback((field, value) => {
|
|
380
|
-
setDataState((prev) => ({
|
|
381
|
-
...prev,
|
|
382
|
-
[field]: value
|
|
383
|
-
}));
|
|
384
|
-
}, []);
|
|
385
|
-
const reset = useCallback((...fields) => {
|
|
386
|
-
if (fields.length === 0) setDataState({ ...defaultsRef.current });
|
|
387
|
-
else setDataState((prev) => {
|
|
388
|
-
const next = { ...prev };
|
|
389
|
-
for (const field of fields) next[field] = defaultsRef.current[field];
|
|
390
|
-
return next;
|
|
391
|
-
});
|
|
392
|
-
}, []);
|
|
393
|
-
const clearErrors = useCallback((...fields) => {
|
|
394
|
-
if (fields.length === 0) setErrors({});
|
|
395
|
-
else setErrors((prev) => {
|
|
396
|
-
const next = { ...prev };
|
|
397
|
-
for (const field of fields) delete next[field];
|
|
398
|
-
return next;
|
|
399
|
-
});
|
|
400
|
-
}, []);
|
|
401
|
-
const clearError = useCallback(() => {
|
|
402
|
-
setError(null);
|
|
403
|
-
}, []);
|
|
404
|
-
const submit = useCallback(async (url, method) => {
|
|
405
|
-
setPending(true);
|
|
406
|
-
setWasSuccessful(false);
|
|
407
|
-
setRecentlySuccessful(false);
|
|
408
|
-
if (successTimeoutRef.current) clearTimeout(successTimeoutRef.current);
|
|
409
|
-
setErrors({});
|
|
410
|
-
setError(null);
|
|
411
|
-
try {
|
|
412
|
-
const response = await fetch(url, {
|
|
413
|
-
method,
|
|
414
|
-
headers: { "Content-Type": "application/json" },
|
|
415
|
-
body: JSON.stringify(data)
|
|
416
|
-
});
|
|
417
|
-
if (response.redirected) {
|
|
418
|
-
window.location.href = response.url;
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
if (response.ok) {
|
|
422
|
-
setWasSuccessful(true);
|
|
423
|
-
setRecentlySuccessful(true);
|
|
424
|
-
const nextDefaults = { ...data };
|
|
425
|
-
defaultsRef.current = nextDefaults;
|
|
426
|
-
setDefaultsState(nextDefaults);
|
|
427
|
-
successTimeoutRef.current = setTimeout(() => setRecentlySuccessful(false), 2e3);
|
|
428
|
-
window.location.reload();
|
|
429
|
-
} else {
|
|
430
|
-
const body = await readActionErrorBody(response);
|
|
431
|
-
const actionError = new VoidActionError({
|
|
432
|
-
body,
|
|
433
|
-
status: response.status,
|
|
434
|
-
statusText: response.statusText,
|
|
435
|
-
url
|
|
436
|
-
});
|
|
437
|
-
const validationErrors = response.status === 422 ? getValidationErrors(body) : null;
|
|
438
|
-
if (validationErrors) {
|
|
439
|
-
setErrors(validationErrors);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
if (categorizeActionError(response.status) === "boundary") throw actionError;
|
|
443
|
-
setError(actionError);
|
|
444
|
-
}
|
|
445
|
-
} finally {
|
|
446
|
-
setPending(false);
|
|
447
|
-
}
|
|
448
|
-
}, [data]);
|
|
449
|
-
return {
|
|
450
|
-
data,
|
|
451
|
-
setData,
|
|
452
|
-
errors,
|
|
453
|
-
error,
|
|
454
|
-
pending,
|
|
455
|
-
hasChanges,
|
|
456
|
-
wasSuccessful,
|
|
457
|
-
recentlySuccessful,
|
|
458
|
-
reset,
|
|
459
|
-
clearErrors,
|
|
460
|
-
clearError,
|
|
461
|
-
post: (url) => submit(url, "POST"),
|
|
462
|
-
put: (url) => submit(url, "PUT"),
|
|
463
|
-
patch: (url) => submit(url, "PATCH"),
|
|
464
|
-
delete: (url) => submit(url, "DELETE")
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
//#endregion
|
|
468
|
-
export { useParams as a, Form as c, useShared as i, useNavigation as n, useRouter as o, useForm as r, Link as s, useIslandForm as t };
|