Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support <input type="file" /> validation #101

Open
mdoury opened this issue Nov 7, 2022 · 7 comments
Open

Support <input type="file" /> validation #101

mdoury opened this issue Nov 7, 2022 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@mdoury
Copy link

mdoury commented Nov 7, 2022

I'm trying to include a file field for image uploading using the unstable_createFileUploadHandler api and would like to include some server side validation in addition to the client validation.

In Issue #8 @danielweinmann said file input validation is unnecessary but in my opinion this is not always true.
I'm building an image processing tool relying on multipart form data and I'd like to ensure that a file is actually submitted by the user, but I'd also like to restrict the type and the size of the files a user can upload.
It would be really handy if file input validation could be done in the same workflow and with the same efficiency as the other input fields, i.e. progressive enhancement, E2E type safety, accessibility, etc.

I really like remix-forms and its apis but this feature is a deal breaker for me, so I really hope you reconsider supporting file upload in the future 🙏

@diogob
Copy link
Contributor

diogob commented Nov 7, 2022

@mdoury do you have any suggestions on how that file validation API would look like? Examples of pseudo-code would greatly help us to design a file uploading feature.

@diogob diogob added the enhancement New feature or request label Nov 7, 2022
@mdoury
Copy link
Author

mdoury commented Nov 10, 2022

@diogob I was thinking of something like this :

import type { ActionArgs } from "@remix-run/node";
import { NodeOnDiskFile } from "@remix-run/node";
import { z } from "zod";
import { file } from "remix-forms";

import { Form } from "~/form";
import { formAction } from "~/form-action";
import { processFile as mutation } from "~/mutations";
import { fileUploadHandler as uploadHandler } from "~/upload-handlers";

const schema = z.object({
  image: file({
    schema: z.instanceof(NodeOnDiskFile),
    accept: ["image/jpeg", "image/jpg", "image/png", "image/webp"] as const,
    maxSize: 5_000_000,
  }),
});

export async function action({ request }: ActionArgs) {
  return formAction({
    request,
    schema,
    mutation,
    successPath: "/success",
    uploadHandler,
  });
}

export default () => <Form schema={schema} encType="multipart/form-data" />;

Users would provide the uploadHandler, this way it can be customized and/or composed.
The file helper would allow users to specify the schema expected from the uploadHandler, the file type corresponding to the accept attribute, as well as the maximum allowed file size.

remix-form would handle FormData parsing using unstable_parseMultipartFormData.
It would also generate an <input type="file" /> field with the appropriate attributes, a11y attributes, and basic error handling, as well as the client side file size check.

Note that the encType prop on the Form component may not be necessary as it may be possible to infer that the schema contains one or more fields configured using the file helper.

What do you think?

@diogob diogob self-assigned this Nov 10, 2022
@diogob
Copy link
Contributor

diogob commented Nov 10, 2022

@mdoury I like this idea. I'll play around with the code and gather a bit more info on the implementation details and post my findings here.

@mdoury
Copy link
Author

mdoury commented Nov 10, 2022

@diogob Cool, let me know if I can help.

@ben-smartbear
Copy link

Any update to this?

@founderblocks-sils
Copy link

Hey, I found this as a good source of inspiration, using that making a decently working custom field for files, using the watch function:

https://codesandbox.io/s/react-hook-form-uploadfile-with-thumbnail-preview--drag-and-drop-p11gy?file=/src/App.js

That paired with the code at #8 should make it possible to work with remix-forms and files. Builtin support would be really splendid though, maybe this helps with that too :)

@janhesters
Copy link

Would be great, if this was supported!

Screenshot 2023-04-08 at 10 48 53

Also, would be awesome if this is designed in a way to handle "drag-and-drop" as well as regular uploads. (That you can somehow decide which input to render.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants