Files
hideyoshi-blog/plan-fileUploadField.prompt.md

1.9 KiB

Plan: Refactor FileUploadSection into generic FileUploadField

Replace the composite, internally-coupled FileUploadSection with a generic, controlled FileUploadField component. Business logic (validation helpers, toast errors, URL generation) moves up into CreateArticleForm, and two FileUploadField instances replace the single FileUploadSection.

Steps

  1. Create file-upload-field.tsx as a controlled FileUploadField component accepting file: File | null, onFileChange: (file: File | null) => void, accept, validate, label, description, and error props — rendering the FileUpload/Field UI shell with no internal business logic.

  2. Move isImageFile, isContentFile, generateFakeImageUrl, and rejection-toast handlers into create-article-form.tsx, adding coverImageFile and contentFile state entries (or keeping them as useForm values directly).

  3. Replace the <FileUploadSection> block in create-article-form.tsx with two <FileUploadField> instances (one for cover image, one for content), wiring each one to the form state via Controller or direct setValue.

  4. Delete file-upload-section.tsx now that it has no consumers.

Further Considerations

  1. onFileChange vs setFileonFileChange follows idiomatic React event-prop naming; setFile reads more like a state-setter leak. onFileChange is recommended but either works.

  2. State ownership for files — Cover image needs a File reference for URL revocation cleanup; should this live in a useState inside the form or in the FileUploadField itself via a ref? Keeping it inside the form is cleaner for reset logic.

  3. Null on clear — The onFileChange(null) case (user deletes the file) should also clear the related form field value (coverImageUrl'', content''), so the handler in the form needs to handle both File and null.