fileField.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import {Fragment, useState} from 'react';
  2. import omit from 'lodash/omit';
  3. import FormField from 'sentry/components/forms/formField';
  4. import Input from 'sentry/components/input';
  5. // XXX(epurkhiser): This is wrong, it should not be inheriting these props
  6. import {InputFieldProps} from './inputField';
  7. export interface FileFieldProps extends Omit<InputFieldProps, 'type' | 'accept'> {
  8. accept?: string[];
  9. // TODO(dcramer): multiple is native to the file input type, but not yet supported
  10. // multiple?: boolean;
  11. }
  12. // XXX(dcramer): This stores files in memory - serialized into the forms values
  13. // which is not ideal, but is compatible with the API-side SerializedFileField.
  14. // TODO(dcramer): it'd be nice if the form api supported a validation state, so
  15. // async controls like this would could finish their work and disable submission.
  16. // Until that is done though if you try to submit the form while this is uploading
  17. // you will just submit the form without the field.
  18. export default function FileField({accept, ...props}: FileFieldProps) {
  19. const [isUploading, setUploading] = useState(false);
  20. const handleFile = (onChange, e) => {
  21. const file = e.target.files[0];
  22. const reader = new FileReader();
  23. setUploading(true);
  24. reader.addEventListener(
  25. 'load',
  26. () => {
  27. onChange([file.name, (reader.result as string).split(',')[1]], e);
  28. setUploading(false);
  29. },
  30. false
  31. );
  32. reader.readAsDataURL(file);
  33. };
  34. return (
  35. <FormField {...props}>
  36. {({children: _children, onChange, ...fieldProps}) => (
  37. <Fragment>
  38. <Input
  39. {...omit(fieldProps, 'value', 'onBlur', 'onKeyDown')}
  40. type="file"
  41. accept={accept?.join(', ')}
  42. onChange={e => handleFile(onChange, e)}
  43. />
  44. {isUploading ? (
  45. <div>This is a janky upload indicator. Wait to hit save!</div>
  46. ) : (
  47. ''
  48. )}
  49. </Fragment>
  50. )}
  51. </FormField>
  52. );
  53. }