@tinvar/react 0.0.0-stage → 0.4.1
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/LICENSE +21 -0
- package/package.json +168 -4
- package/src/action-server.js +41 -0
- package/src/action.d.ts +68 -0
- package/src/action.js +167 -0
- package/src/bootstrap.js +153 -0
- package/src/channel.d.ts +46 -0
- package/src/channel.js +132 -0
- package/src/client-modules.d.ts +8 -0
- package/src/client-modules.js +88 -0
- package/src/client.d.ts +36 -0
- package/src/client.js +42 -0
- package/src/compose-route.d.ts +33 -0
- package/src/compose-route.js +107 -0
- package/src/csrf.d.ts +11 -0
- package/src/csrf.js +49 -0
- package/src/deferred-boundary.d.ts +61 -0
- package/src/deferred-boundary.js +646 -0
- package/src/deferred-groups.d.ts +24 -0
- package/src/deferred-groups.js +198 -0
- package/src/deferred-revalidation.d.ts +37 -0
- package/src/deferred-revalidation.js +108 -0
- package/src/deferred-triggers.d.ts +26 -0
- package/src/deferred-triggers.js +172 -0
- package/src/deferred.d.ts +24 -0
- package/src/deferred.jsx +100 -0
- package/src/document-load.js +95 -0
- package/src/endpoint.d.ts +87 -0
- package/src/endpoint.js +304 -0
- package/src/form-data.js +219 -0
- package/src/form.d.ts +177 -0
- package/src/form.js +615 -0
- package/src/forms.d.ts +4 -0
- package/src/forms.js +10 -0
- package/src/fragment-client.d.ts +70 -0
- package/src/fragment-client.js +510 -0
- package/src/head.d.ts +85 -0
- package/src/head.js +360 -0
- package/src/inbox-view.d.ts +17 -0
- package/src/inbox-view.js +105 -0
- package/src/inbox.d.ts +108 -0
- package/src/inbox.js +293 -0
- package/src/index.combined.d.ts +31 -0
- package/src/index.d.ts +5 -0
- package/src/index.js +29 -0
- package/src/index.server.d.ts +4 -0
- package/src/index.server.js +8 -0
- package/src/infinite-scroll.d.ts +108 -0
- package/src/infinite-scroll.js +715 -0
- package/src/layout-props.d.ts +30 -0
- package/src/layout-props.js +143 -0
- package/src/link-click.d.ts +3 -0
- package/src/link-click.js +68 -0
- package/src/link.d.ts +63 -0
- package/src/link.js +274 -0
- package/src/live.d.ts +65 -0
- package/src/live.js +977 -0
- package/src/merge-slot.d.ts +41 -0
- package/src/merge-slot.js +253 -0
- package/src/merge.d.ts +111 -0
- package/src/merge.js +149 -0
- package/src/once-slot.d.ts +14 -0
- package/src/once-slot.js +75 -0
- package/src/once-store.d.ts +26 -0
- package/src/once-store.js +211 -0
- package/src/once.d.ts +44 -0
- package/src/once.js +65 -0
- package/src/optimistic.d.ts +14 -0
- package/src/optimistic.js +159 -0
- package/src/optional.d.ts +10 -0
- package/src/optional.js +31 -0
- package/src/page-root.d.ts +56 -0
- package/src/page-root.js +455 -0
- package/src/payload.d.ts +15 -0
- package/src/payload.js +101 -0
- package/src/poll.d.ts +55 -0
- package/src/poll.js +224 -0
- package/src/precognition.js +190 -0
- package/src/prefetch-cache.d.ts +46 -0
- package/src/prefetch-cache.js +256 -0
- package/src/progress.d.ts +38 -0
- package/src/progress.js +243 -0
- package/src/remember-store.d.ts +50 -0
- package/src/remember-store.js +486 -0
- package/src/rescue.d.ts +10 -0
- package/src/rescue.js +30 -0
- package/src/resumable.js +822 -0
- package/src/resume-store.js +364 -0
- package/src/route.d.ts +50 -0
- package/src/route.js +227 -0
- package/src/router-hooks.js +234 -0
- package/src/router.d.ts +586 -0
- package/src/router.js +3555 -0
- package/src/segment.d.ts +36 -0
- package/src/segment.js +116 -0
- package/src/server.d.ts +71 -0
- package/src/server.js +242 -0
- package/src/submit.js +333 -0
- package/src/telemetry.d.ts +71 -0
- package/src/telemetry.js +851 -0
- package/src/testing.d.ts +89 -0
- package/src/testing.js +634 -0
- package/src/transfer.d.ts +48 -0
- package/src/transfer.js +135 -0
- package/src/transport.js +390 -0
- package/src/upload.d.ts +342 -0
- package/src/upload.js +1240 -0
- package/src/use-channel.d.ts +21 -0
- package/src/use-channel.js +51 -0
- package/src/use-form.d.ts +86 -0
- package/src/use-form.js +432 -0
- package/src/use-http.d.ts +56 -0
- package/src/use-http.js +248 -0
- package/src/use-inbox.d.ts +41 -0
- package/src/use-inbox.js +201 -0
- package/src/use-remember.d.ts +10 -0
- package/src/use-remember.js +132 -0
- package/src/when-mounted.d.ts +15 -0
- package/src/when-mounted.js +27 -0
- package/README.md +0 -3
package/src/upload.d.ts
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import type { ReactNode, RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
export declare const UPLOAD_PATH: '/_upload';
|
|
4
|
+
|
|
5
|
+
/** Where a ticket a page has outlived is issued again. */
|
|
6
|
+
export declare const UPLOAD_REFRESH_PATH: '/_upload/refresh';
|
|
7
|
+
export declare const UPLOAD_DIRECT_PATH: '/_upload/direct';
|
|
8
|
+
export declare const UPLOAD_COMPLETE_PATH: '/_upload/complete';
|
|
9
|
+
|
|
10
|
+
/** Where a resumable upload begins, under the ticket (ADR 0143). */
|
|
11
|
+
export declare const UPLOAD_SESSION_PATH: '/_upload/session';
|
|
12
|
+
/** Where it is asked how much of a resumable upload the server holds. */
|
|
13
|
+
export declare const UPLOAD_OFFSET_PATH: '/_upload/session/offset';
|
|
14
|
+
/** Where a chunk is appended through PHP, at the offset the server holds. */
|
|
15
|
+
export declare const UPLOAD_CHUNK_PATH: '/_upload/session/chunk';
|
|
16
|
+
/** Where the URLs for the next parts to the store are asked for. */
|
|
17
|
+
export declare const UPLOAD_PARTS_PATH: '/_upload/session/parts';
|
|
18
|
+
/** Where an upload sent in parts is completed. */
|
|
19
|
+
export declare const UPLOAD_SESSION_COMPLETE_PATH: '/_upload/session/complete';
|
|
20
|
+
/** Where a resumable upload is given up, its room given back. */
|
|
21
|
+
export declare const UPLOAD_ABORT_PATH: '/_upload/session/abort';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Gives a resumable upload's session up on the server -- its bytes removed,
|
|
25
|
+
* its room given back -- whatever the server answers. The record that
|
|
26
|
+
* remembers it is the caller's to delete from its resume store.
|
|
27
|
+
*/
|
|
28
|
+
export declare function abortUpload(session: string): Promise<void>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* What a resumable upload remembers across a refresh, in IndexedDB: the
|
|
32
|
+
* session the server signed and the file's name, size and fingerprint --
|
|
33
|
+
* never its bytes -- and, where the browser has one, a handle to reopen it.
|
|
34
|
+
*/
|
|
35
|
+
export interface ResumeRecord {
|
|
36
|
+
id: string;
|
|
37
|
+
scope: string;
|
|
38
|
+
fingerprint: string;
|
|
39
|
+
session: string;
|
|
40
|
+
mode: 'chunks' | 'parts';
|
|
41
|
+
name: string;
|
|
42
|
+
size: number;
|
|
43
|
+
type: string;
|
|
44
|
+
lastModified: number;
|
|
45
|
+
offset: number;
|
|
46
|
+
createdAt: number;
|
|
47
|
+
/** Seconds since the epoch, as the server set it. */
|
|
48
|
+
expiresAt: number;
|
|
49
|
+
handle?: unknown;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Where resumable uploads are remembered. Every method settles; none throws. */
|
|
53
|
+
export interface ResumeStore {
|
|
54
|
+
/** Forgets every record unless the store's are already the session and user $binding (the router's) names; all of them for null. */
|
|
55
|
+
purge?(binding: string | null): Promise<void>;
|
|
56
|
+
get(id: string): Promise<ResumeRecord | null>;
|
|
57
|
+
put(record: ResumeRecord): Promise<void>;
|
|
58
|
+
delete(id: string): Promise<void>;
|
|
59
|
+
inScope(scope: string): Promise<ResumeRecord[]>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The browser's resume store, in IndexedDB; one that remembers nothing where IndexedDB cannot be had. */
|
|
63
|
+
export declare function indexedDbResumeStore(): ResumeStore;
|
|
64
|
+
/** A resume store in memory, for tests. */
|
|
65
|
+
export declare function memoryResumeStore(): ResumeStore;
|
|
66
|
+
|
|
67
|
+
/** Where a resumable upload stands, while it is going: sending, waiting out a dropped network, or asking where to go on. */
|
|
68
|
+
export type ResumableState = 'uploading' | 'paused' | 'resuming';
|
|
69
|
+
|
|
70
|
+
/** The session a resumable upload goes on in, and the id of the record that remembers it (null where none does). */
|
|
71
|
+
export interface ResumableSession {
|
|
72
|
+
session: string;
|
|
73
|
+
id: string | null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface UploadProgress {
|
|
77
|
+
loaded: number;
|
|
78
|
+
total: number | undefined;
|
|
79
|
+
percentage: number | undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** What /_upload answered: the reference the form sends, and the file as the server saw it. */
|
|
83
|
+
export interface Uploaded {
|
|
84
|
+
/** Opaque: what the action parameter is posted as. */
|
|
85
|
+
upload: string;
|
|
86
|
+
/** What the client called the file, cleaned: metadata only. */
|
|
87
|
+
name: string;
|
|
88
|
+
size: number;
|
|
89
|
+
/** The type the server sniffed the bytes as. */
|
|
90
|
+
type: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Why an upload did not go in, for the app to say in its own words:
|
|
95
|
+
* `too_large` (413), `type` (the bytes are not a type the field takes,
|
|
96
|
+
* 415), `invalid` (empty, or no file, 422), `refused` (the ticket has run
|
|
97
|
+
* out, or is not this session's -- reload the page, 403), `signed_out`
|
|
98
|
+
* (401), `throttled` (429), `quota` (the user's files fill their quota, 507),
|
|
99
|
+
* `infected` (a scanner found malware in it, 422), `unavailable` (it could
|
|
100
|
+
* not be scanned, 503),
|
|
101
|
+
* `expired` (the page outlived its session, 419),
|
|
102
|
+
* `network`, or `failed`.
|
|
103
|
+
*/
|
|
104
|
+
export type UploadErrorKind =
|
|
105
|
+
| 'too_large'
|
|
106
|
+
| 'type'
|
|
107
|
+
| 'invalid'
|
|
108
|
+
| 'refused'
|
|
109
|
+
| 'signed_out'
|
|
110
|
+
| 'throttled'
|
|
111
|
+
| 'quota'
|
|
112
|
+
| 'infected'
|
|
113
|
+
| 'unavailable'
|
|
114
|
+
| 'expired'
|
|
115
|
+
| 'network'
|
|
116
|
+
| 'failed';
|
|
117
|
+
|
|
118
|
+
export interface UploadError {
|
|
119
|
+
kind: UploadErrorKind;
|
|
120
|
+
status: number;
|
|
121
|
+
code: string | null;
|
|
122
|
+
/** The digest to quote to support, when the server gave one. */
|
|
123
|
+
reference: string | null;
|
|
124
|
+
retryAfter: number | null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export type UploadOutcome =
|
|
128
|
+
{ type: 'uploaded'; file: Uploaded } | { type: 'error'; error: UploadError } | { type: 'cancelled' };
|
|
129
|
+
|
|
130
|
+
export interface UploadOptions {
|
|
131
|
+
ticket: string;
|
|
132
|
+
file: Blob;
|
|
133
|
+
url?: string;
|
|
134
|
+
/** Refuses a larger file without sending it; the server holds the real limit. */
|
|
135
|
+
maxBytes?: number;
|
|
136
|
+
signal?: AbortSignal;
|
|
137
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
138
|
+
/** Asks for the ticket again once, on a refusal, and sends the file again under it. */
|
|
139
|
+
refresh?: boolean;
|
|
140
|
+
refreshUrl?: string;
|
|
141
|
+
/** Told the ticket a refresh issued, for the uploads after this one. */
|
|
142
|
+
onTicket?: (ticket: string) => void;
|
|
143
|
+
/**
|
|
144
|
+
* Sends the file straight to the application's object store, by a URL
|
|
145
|
+
* /_upload/direct presigns for its size, and has /_upload/complete check
|
|
146
|
+
* and keep it. The bucket must allow this origin's PUT.
|
|
147
|
+
*/
|
|
148
|
+
direct?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Sends it as a resumable upload (ADR 0143): in chunks through PHP, or --
|
|
151
|
+
* with `direct` -- in parts to the store, each from the byte the server
|
|
152
|
+
* holds. A dropped network is waited out; the same file sent again after
|
|
153
|
+
* a refresh goes on from where the server is. A server that takes none
|
|
154
|
+
* has it sent whole.
|
|
155
|
+
*/
|
|
156
|
+
resumable?: boolean;
|
|
157
|
+
/** Told when a resumable upload pauses for the network, asks where to go on, and sends again. */
|
|
158
|
+
onState?: (state: ResumableState) => void;
|
|
159
|
+
/**
|
|
160
|
+
* Told the session a resumable upload goes on in, once it is known. A
|
|
161
|
+
* cancel through `signal` keeps it on the server for a later page to go
|
|
162
|
+
* on with; a caller giving the upload up for good gives it up too.
|
|
163
|
+
*/
|
|
164
|
+
onSession?: (session: ResumableSession) => void;
|
|
165
|
+
/** A FileSystemFileHandle the file was chosen through, kept so it can be reopened after a refresh. */
|
|
166
|
+
handle?: unknown;
|
|
167
|
+
/** Where resumable uploads are remembered: IndexedDB unless given. */
|
|
168
|
+
resumeStore?: ResumeStore;
|
|
169
|
+
/** Seconds between tries after a network drop or a 5xx. */
|
|
170
|
+
backoff?: number[];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Sends one file to /_upload under a ticket. Never throws for an outcome. */
|
|
174
|
+
export declare function uploadFile(options: UploadOptions): Promise<UploadOutcome>;
|
|
175
|
+
|
|
176
|
+
export type RefreshOutcome =
|
|
177
|
+
| { type: 'refreshed'; ticket: string; expiresAt: number }
|
|
178
|
+
| { type: 'error'; error: UploadError }
|
|
179
|
+
| { type: 'cancelled' };
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Asks for a ticket the page holds to be issued again: for the same
|
|
183
|
+
* session, user, action and record, for another hour, and never past a day
|
|
184
|
+
* from its first issue.
|
|
185
|
+
*/
|
|
186
|
+
export declare function refreshTicket(options: {
|
|
187
|
+
ticket: string;
|
|
188
|
+
url?: string;
|
|
189
|
+
signal?: AbortSignal;
|
|
190
|
+
}): Promise<RefreshOutcome>;
|
|
191
|
+
|
|
192
|
+
export type UploadStatus = 'idle' | 'uploading' | 'paused' | 'resuming' | 'uploaded' | 'error';
|
|
193
|
+
|
|
194
|
+
export interface UseUploadOptions {
|
|
195
|
+
/** The ticket the page's loader issued for this action parameter. */
|
|
196
|
+
ticket: string;
|
|
197
|
+
url?: string;
|
|
198
|
+
maxBytes?: number;
|
|
199
|
+
/** Runs once the reference is in state, so a submit from it sends it. */
|
|
200
|
+
onUploaded?: (file: Uploaded) => void;
|
|
201
|
+
onError?: (error: UploadError) => void;
|
|
202
|
+
/** Sends each file straight to the object store (see UploadOptions). */
|
|
203
|
+
direct?: boolean;
|
|
204
|
+
/** Sends each file as a resumable upload, and offers to go on with one a refresh interrupted (see UploadOptions). */
|
|
205
|
+
resumable?: boolean;
|
|
206
|
+
resumeStore?: ResumeStore;
|
|
207
|
+
backoff?: number[];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** An upload of this field the server still holds part of, begun before a refresh, a closed tab or a crash. */
|
|
211
|
+
export interface PendingUpload {
|
|
212
|
+
name: string;
|
|
213
|
+
size: number;
|
|
214
|
+
/** The bytes the server holds. */
|
|
215
|
+
offset: number;
|
|
216
|
+
percentage: number;
|
|
217
|
+
/** Whether the browser kept a handle to the file, so resuming asks only for permission to read it. */
|
|
218
|
+
reopenable: boolean;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface UploadState {
|
|
222
|
+
/** `paused` while a dropped network is waited out, `resuming` while the server is asked where to go on. */
|
|
223
|
+
status: UploadStatus;
|
|
224
|
+
/** True while it is sending, paused or resuming. */
|
|
225
|
+
uploading: boolean;
|
|
226
|
+
paused: boolean;
|
|
227
|
+
resuming: boolean;
|
|
228
|
+
progress: UploadProgress | null;
|
|
229
|
+
file: Uploaded | null;
|
|
230
|
+
error: UploadError | null;
|
|
231
|
+
/** What the form sends under the parameter's name, once the upload is in. */
|
|
232
|
+
reference: string | null;
|
|
233
|
+
/** With `resumable`: an upload the server still holds part of, to offer to go on with. */
|
|
234
|
+
pending: PendingUpload | null;
|
|
235
|
+
/** Uploads a file, cancelling one still going; the file it holds part of goes on from there. */
|
|
236
|
+
upload: (file: Blob, options?: { handle?: unknown }) => Promise<UploadOutcome>;
|
|
237
|
+
/**
|
|
238
|
+
* Goes on with `pending`: reopening the file where the browser kept a
|
|
239
|
+
* handle to it -- call it from a click, for the permission prompt -- and
|
|
240
|
+
* answering null where the person has to choose the file again.
|
|
241
|
+
*/
|
|
242
|
+
resume: () => Promise<UploadOutcome | null>;
|
|
243
|
+
/** Gives up `pending`, on the server too: its bytes removed and its room given back. */
|
|
244
|
+
discardPending: () => Promise<void>;
|
|
245
|
+
/** Cancels the upload going; with `resumable`, gives its session up on the server too. */
|
|
246
|
+
cancel: () => void;
|
|
247
|
+
/** Empties the field, cancelling the upload going and, with `resumable`, giving its session up. */
|
|
248
|
+
reset: () => void;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** One upload's state, for a field that takes one file. */
|
|
252
|
+
export declare function useUpload(options: UseUploadOptions): UploadState;
|
|
253
|
+
|
|
254
|
+
export interface UploadFieldSlot extends UploadState {
|
|
255
|
+
/** Opens the file input -- or, with `resumable`, the browser's own picker where it keeps a handle to the file. */
|
|
256
|
+
choose: () => void;
|
|
257
|
+
/** Goes on with `pending`, opening the picker for the person to choose the file again where it must. */
|
|
258
|
+
resume: () => Promise<UploadOutcome | null>;
|
|
259
|
+
/**
|
|
260
|
+
* Whether script runs. Until it does -- drawn by the server, or with no
|
|
261
|
+
* script at all -- the file input is named and the form, sent as
|
|
262
|
+
* multipart, posts the file to the action itself: show the input, and a
|
|
263
|
+
* button that submits the form.
|
|
264
|
+
*/
|
|
265
|
+
scripted: boolean;
|
|
266
|
+
/** Props for the file input: named only until script runs, so script never posts the file. */
|
|
267
|
+
input: {
|
|
268
|
+
ref: RefObject<HTMLInputElement | null>;
|
|
269
|
+
type: 'file';
|
|
270
|
+
accept: string | undefined;
|
|
271
|
+
onChange: (event: { currentTarget: HTMLInputElement }) => void;
|
|
272
|
+
name: string | undefined;
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface UploadFieldProps extends UseUploadOptions {
|
|
277
|
+
/** The action parameter the reference is posted as. */
|
|
278
|
+
name: string;
|
|
279
|
+
accept?: string;
|
|
280
|
+
children?: (field: UploadFieldSlot) => ReactNode;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* A form field that uploads the file chosen in it to /_upload and posts the
|
|
285
|
+
* reference under `name`; it draws nothing but the hidden input.
|
|
286
|
+
*/
|
|
287
|
+
export declare function UploadField(props: UploadFieldProps): ReactNode;
|
|
288
|
+
|
|
289
|
+
export interface UploadEntry {
|
|
290
|
+
key: number;
|
|
291
|
+
/** `paused` and `resuming` too, for a resumable upload. */
|
|
292
|
+
status: UploadStatus;
|
|
293
|
+
progress: UploadProgress | null;
|
|
294
|
+
file: Uploaded | null;
|
|
295
|
+
error: UploadError | null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export interface UseUploadsOptions extends UseUploadOptions {
|
|
299
|
+
/** Refuses files past it without sending them; the server holds the real limit. */
|
|
300
|
+
maxFiles?: number;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface UploadsState {
|
|
304
|
+
entries: UploadEntry[];
|
|
305
|
+
uploading: boolean;
|
|
306
|
+
/** What the form sends under the parameter's name: a reference for each file that went in. */
|
|
307
|
+
references: string[];
|
|
308
|
+
/** Uploads each file, one after another, under the one ticket. */
|
|
309
|
+
upload: (files: Iterable<Blob>) => Promise<UploadOutcome[]>;
|
|
310
|
+
/** Drops a file: cancelled if it is going, never sent if queued; with `resumable`, its session given up. */
|
|
311
|
+
remove: (key: number) => void;
|
|
312
|
+
/** Drops every file, sending none still queued; with `resumable`, their sessions given up. */
|
|
313
|
+
reset: () => void;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** The state of a parameter that takes several files (an UploadList). */
|
|
317
|
+
export declare function useUploads(options: UseUploadsOptions): UploadsState;
|
|
318
|
+
|
|
319
|
+
export interface UploadsFieldSlot extends UploadsState {
|
|
320
|
+
choose: () => void;
|
|
321
|
+
input: {
|
|
322
|
+
ref: RefObject<HTMLInputElement | null>;
|
|
323
|
+
type: 'file';
|
|
324
|
+
multiple: true;
|
|
325
|
+
accept: string | undefined;
|
|
326
|
+
onChange: (event: { currentTarget: HTMLInputElement }) => void;
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export interface UploadsFieldProps extends UseUploadsOptions {
|
|
331
|
+
/** The action parameter the references are posted as, each under `name[]`. */
|
|
332
|
+
name: string;
|
|
333
|
+
accept?: string;
|
|
334
|
+
children?: (field: UploadsFieldSlot) => ReactNode;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* A form field for a parameter that takes several files: it uploads each
|
|
339
|
+
* file chosen in it and posts every reference, drawing nothing but the
|
|
340
|
+
* hidden inputs.
|
|
341
|
+
*/
|
|
342
|
+
export declare function UploadsField(props: UploadsFieldProps): ReactNode;
|