Skip to content

Commit 62e875b

Browse files
committed
onSubmit handler should have correct type
1 parent 39666c7 commit 62e875b

File tree

1 file changed

+48
-35
lines changed

1 file changed

+48
-35
lines changed

packages/react/src/Uploader.tsx

+48-35
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { As, Component, Props, Options, HTMLProps } from 'ariakit-react-utils'
2-
import type { ChangeEvent } from 'react'
2+
import type { ChangeEvent, FormEventHandler } from 'react'
33
import type { AnyLink, CARMetadata, ProgressStatus } from '@w3ui/core'
44

55
import React, {
@@ -43,7 +43,7 @@ export interface UploaderContextState {
4343
* A callback that can be passed to an `onSubmit` handler to
4444
* upload `file` to web3.storage via the w3up API.
4545
*/
46-
handleUploadSubmit?: (e: Event) => Promise<void>
46+
handleUploadSubmit?: FormEventHandler<HTMLFormElement>
4747
/**
4848
* The CID of a successful upload
4949
*/
@@ -158,7 +158,7 @@ export const UploaderRoot: Component<UploaderRootProps> = createComponent(
158158
const [uploadAsCAR, setUploadAsCAR] = useState(defaultUploadAsCAR)
159159
const [dataCID, setDataCID] = useState<AnyLink>()
160160
const [status, setStatus] = useState(UploadStatus.Idle)
161-
const [error, setError] = useState()
161+
const [error, setError] = useState<Error>()
162162
const [storedDAGShards, setStoredDAGShards] = useState<UploaderContextState['storedDAGShards']>([])
163163
const [uploadProgress, setUploadProgress] = useState<UploadProgress>({})
164164

@@ -167,42 +167,55 @@ export const UploaderRoot: Component<UploaderRootProps> = createComponent(
167167
setStatus(UploadStatus.Idle)
168168
}
169169

170-
const handleUploadSubmit = async (e: Event): Promise<void> => {
170+
const handleUploadSubmit: FormEventHandler<HTMLFormElement> = (e) => {
171171
e.preventDefault()
172-
// file !== undefined should be unecessary but is here to make tsc happy
173-
if ((client !== undefined) && (files !== undefined) && (file !== undefined)) {
174-
try {
175-
setError(undefined)
176-
setStatus(UploadStatus.Uploading)
177-
const storedShards: CARMetadata[] = []
178-
setStoredDAGShards(storedShards)
179-
const uploadOptions = {
180-
onShardStored (meta: CARMetadata) {
181-
storedShards.push(meta)
182-
setStoredDAGShards([...storedShards])
183-
},
184-
onUploadProgress (status: ProgressStatus) {
185-
setUploadProgress(statuses => ({ ...statuses, [status.url ?? '']: status }))
186-
}
187-
}
188-
const cid = files.length > 1
189-
? await client.uploadDirectory(files, uploadOptions)
190-
: (uploadAsCAR
191-
? await client.uploadCAR(file, uploadOptions)
192-
: (wrapInDirectory
193-
? await client.uploadDirectory(files, uploadOptions)
194-
: await client.uploadFile(file, uploadOptions)))
172+
if ((client === undefined)) {
173+
// eslint-disable-next-line no-console
174+
console.error('No client available for upload. Ignoring upload attempt.')
175+
return
176+
}
177+
178+
// The application should only attempt to submit once files are selected.
179+
if ((files === undefined) || (file === undefined)) {
180+
// eslint-disable-next-line no-console
181+
console.error('No no files given to upload. Ignoring upload attempt.')
182+
return
183+
}
195184

196-
setDataCID(cid)
197-
setStatus(UploadStatus.Succeeded)
198-
if (onUploadComplete !== undefined) {
199-
onUploadComplete({ file, files, dataCID: cid })
185+
const doUpload = async (): Promise<void> => {
186+
setError(undefined)
187+
setStatus(UploadStatus.Uploading)
188+
const storedShards: CARMetadata[] = []
189+
setStoredDAGShards(storedShards)
190+
const uploadOptions = {
191+
onShardStored (meta: CARMetadata) {
192+
storedShards.push(meta)
193+
setStoredDAGShards([...storedShards])
194+
},
195+
onUploadProgress (status: ProgressStatus) {
196+
setUploadProgress(statuses => ({ ...statuses, [status.url ?? '']: status }))
200197
}
201-
} catch (error_: any) {
202-
setError(error_)
203-
setStatus(UploadStatus.Failed)
198+
}
199+
const cid = files.length > 1
200+
? await client.uploadDirectory(files, uploadOptions)
201+
: (uploadAsCAR
202+
? await client.uploadCAR(file, uploadOptions)
203+
: (wrapInDirectory
204+
? await client.uploadDirectory(files, uploadOptions)
205+
: await client.uploadFile(file, uploadOptions)))
206+
207+
setDataCID(cid)
208+
setStatus(UploadStatus.Succeeded)
209+
if (onUploadComplete !== undefined) {
210+
onUploadComplete({ file, files, dataCID: cid })
204211
}
205212
}
213+
214+
doUpload().catch((error_: unknown) => {
215+
const error = (error_ instanceof Error) ? error_ : new Error(String(error_))
216+
setError(error)
217+
setStatus(UploadStatus.Failed)
218+
})
206219
}
207220

208221
const uploaderContextValue =
@@ -307,7 +320,7 @@ export type UploaderFormProps<T extends As = 'form'> = Props<UploaderFormOptions
307320
*/
308321
export const UploaderForm: Component<UploaderFormProps> = createComponent((props) => {
309322
const [{ handleUploadSubmit }] = useContext(UploaderContext)
310-
return createElement('form', { ...props, onSubmit: handleUploadSubmit })
323+
return createElement('form', { ...props, onSubmit: handleUploadSubmit satisfies React.ComponentProps<'form'>['onSubmit'] })
311324
})
312325

313326
/**

0 commit comments

Comments
 (0)