npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-image-upload-s3

v1.1.3

Published

A React component that renders an image input and uploads to an S3 bucket. Optionally can perform resizing and compressing of the image.

Downloads

48

Readme

Summary

A React component that renders an image input and uploads to an S3 bucket. Optionally can perform resizing and compressing of the image.

  • ready to use an input element with preview of a image
  • resizing and compressing of an image on frontend to reduce traffic and increase speed of uploading

How does it look like

Editor

Installation

npm install react-image-upload-s3

Example 1

autoUpload=True

import React, { useState, useRef, useEffect } from 'react';
import { ImageS3Upload } from 'react-image-upload-s3';

function App() {
  const URL_GENERATE_S3_URLKEY = 'https://yourserver.com/s3/sign/';
  const SERVER_PHOTO = 'https://example.amazonaws.com/';

  const resizerOptions = {
    enabled: true,
    autoResize: true, // otherwise resizing will be preform before uploading, the parametr doesn't make sense if autoUpload = True
    maxWidth: 1280,
    maxHeight: 1280,
    compressFormat: 'JPEG',
    quality: 70,
    rotation: 0, // rotation is limited to multiples of 90 degrees
  };

  const onFinish = (isSuccessful: boolean, urlImage: string) => {
    if (isSuccessful) {
      console.log('onFinish', urlImage);
    } else {
      console.log('onFinish', 'Unsuccessful');
    }
  };

  return (
    <div
      style={{
        maxWidth: '200px',
        margin: '10px',
        padding: '10px',
        border: 'solid 1px black',
      }}
    >
      <ImageS3Upload
        signingUrl={URL_GENERATE_S3_URLKEY}
        autoUpload={true}
        serverPhoto={SERVER_PHOTO}
        onFinish={onFinish}
        resizer={resizerOptions}
      />
    </div>
  );
}

export default App;

Example 2

autoUpload=False

import React, { useState, useRef, useEffect } from 'react';
import { ImageS3Upload } from 'react-image-upload-s3';

function App() {
  const URL_GENERATE_S3_URLKEY = 'https://yourserver.com/s3/sign/';
  const SERVER_PHOTO = 'https://example.amazonaws.com/';

  const resizerOptions = {
    enabled: true,
    autoResize: true, // otherwise resizing will be preform before uploading, the parametr doesn't make sense if autoUpload = True
    maxWidth: 1280,
    maxHeight: 1280,
    compressFormat: 'JPEG',
    quality: 70,
    rotation: 0, // rotation is limited to multiples of 90 degrees
  };

  const refS3Uploader = useRef(); // to be able to call method uploadFile

  const [comment, setComment] = useState('');
  const [imageS3URL, setImageS3URL] = useState('');

  const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
  const [submitData, setSubmitData] = useState(false);

  useEffect(() => {
    setSubmitData(false);
    submitData && submitingData();
  }, [submitData]);

  const onSubmit = async (e: any) => {
    e.preventDefault();
    setSubmitButtonDisabled(true);
    //@ts-ignore
    const isSuccess = await refS3Uploader.current.uploadFile();
    setSubmitButtonDisabled(false);
    isSuccess && setSubmitData(true);
  };

  const onResizeStart = () => {
    setSubmitButtonDisabled(true);
  };

  const onResizeFinish = () => {
    setSubmitButtonDisabled(false);
  };

  const submitingData = () => {
    const dataToSend = {
      comment,
      imageS3URL,
    };
    console.log('submitingData', dataToSend);
  };

  return (
    <div
      style={{
        maxWidth: '200px',
        margin: '10px',
        padding: '10px',
        border: 'solid 1px black',
      }}
    >
      <form onSubmit={onSubmit}>
        <label htmlFor="id_comment1">Comment</label>
        <input
          type="text"
          id="id_comment1"
          value={comment}
          onChange={e => setComment(e.target.value)}
        />

        <br />
        <br />

        <ImageS3Upload
          signingUrl={URL_GENERATE_S3_URLKEY}
          autoUpload={false}
          serverPhoto={SERVER_PHOTO}
          resizer={resizerOptions}
          onResizeStart={onResizeStart}
          onResizeFinish={onResizeFinish}
          ref={refS3Uploader}
          value={imageS3URL}
          onChange={(e: any) => setImageS3URL(e.target.value)}
        />

        <br />
        <br />

        <input
          type="submit"
          value="Submit"
          style={{ width: '100%' }}
          className="button"
          disabled={submitButtonDisabled}
        ></input>
      </form>
    </div>
  );
}

export default App;

Example 3

autoUpload=True

import React, { useState, useRef, useEffect } from 'react';
import { ImageS3Upload } from 'react-image-upload-s3';

function App() {
  const URL_GENERATE_S3_URLKEY = 'https://yourserver.com/s3/sign/';
  const SERVER_PHOTO = 'https://example.amazonaws.com/';

  const resizerOptions = {
    enabled: true,
    autoResize: true, // otherwise resizing will be preform before uploading
    maxWidth: 1280,
    maxHeight: 1280,
    compressFormat: 'JPEG',
    quality: 70,
    rotation: 0, // rotation is limited to multiples of 90 degrees
  };

  const [comment, setComment] = useState('');
  const [imageS3URL, setImageS3URL] = useState('');

  const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);

  const onSubmit = async (e: any) => {
    e.preventDefault();
    const dataToSend = {
      comment,
      imageS3URL,
    };
    console.log('onSubmit', dataToSend);
  };

  const onStart = () => {
    setSubmitButtonDisabled(true);
  };

  const onFinish = (isSuccessful: boolean) => {
    setSubmitButtonDisabled(false);
    console.log('isSuccessful', isSuccessful);
  };

  return (
    <div
      style={{
        maxWidth: '200px',
        margin: '10px',
        padding: '10px',
        border: 'solid 1px black',
      }}
    >
      <form onSubmit={onSubmit}>
        <label htmlFor="id_comment2">Comment</label>
        <input
          type="text"
          id="id_comment2"
          value={comment}
          onChange={e => setComment(e.target.value)}
        />

        <br />
        <br />

        <ImageS3Upload
          signingUrl={URL_GENERATE_S3_URLKEY}
          autoUpload={true}
          serverPhoto={SERVER_PHOTO}
          onStart={onStart}
          onFinish={onFinish}
          resizer={resizerOptions}
          value={imageS3URL}
          onChange={e => setImageS3URL(e.target.value)}
        />

        <br />
        <br />

        <input
          type="submit"
          value="Submit"
          style={{ width: '100%' }}
          className="button"
          disabled={submitButtonDisabled}
        ></input>
      </form>
    </div>
  );
}

export default App;

Example 4

Multiple components in one form autoUpload=False

import React, { useState, useRef, useEffect } from 'react';
import { ImageS3Upload } from 'react-image-upload-s3';

function App() {
  const URL_GENERATE_S3_URLKEY = 'https://yourserver.com/s3/sign/';
  const SERVER_PHOTO = 'https://example.amazonaws.com/';

  const resizerOptions = {
    enabled: true,
    autoResize: true, // otherwise resizing will be preform before uploading
    maxWidth: 1280,
    maxHeight: 1280,
    compressFormat: 'JPEG',
    quality: 70,
    rotation: 0, // rotation is limited to multiples of 90 degrees
  };

  const refS3Uploader1 = useRef(); // to be able to call method uploadFile
  const refS3Uploader2 = useRef(); // to be able to call method uploadFile
  const refS3Uploader3 = useRef(); // to be able to call method uploadFile

  const [comment1, setComment1] = useState('');
  const [comment2, setComment2] = useState('');
  const [comment3, setComment3] = useState('');
  const [imageS3URL1, setImageS3URL1] = useState('');
  const [imageS3URL2, setImageS3URL2] = useState('');
  const [imageS3URL3, setImageS3URL3] = useState('');

  const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
  const [submitData, setSubmitData] = useState(false);

  useEffect(() => {
    setSubmitData(false);
    submitData && dataToSubmit();
  }, [submitData]);

  const onSubmit = async (e: any) => {
    e.preventDefault();
    setSubmitButtonDisabled(true);
    Promise.all([
      //@ts-ignore
      refS3Uploader1.current.uploadFile(),
      //@ts-ignore
      refS3Uploader2.current.uploadFile(),
      //@ts-ignore
      refS3Uploader3.current.uploadFile(),
    ]).then(values => {
      setSubmitButtonDisabled(false);
      let result = true;
      values.forEach(value => {
        if (!value) result = false;
      });
      result && setSubmitData(true);
    });
  };

  const dataToSubmit = () => {
    const data = {
      comment1: comment1,
      image1: imageS3URL1,
      comment2: comment2,
      image2: imageS3URL2,
      comment3: comment3,
      image3: imageS3URL3,
    };
    console.log('submitData', data);
  };

  const onResizeStart1 = () => {
    setSubmitButtonDisabled(true);
  };
  const onResizeStart2 = () => {
    setSubmitButtonDisabled(true);
  };
  const onResizeStart3 = () => {
    setSubmitButtonDisabled(true);
  };

  const onResizeFinish1 = () => {
    setSubmitButtonDisabled(false);
  };
  const onResizeFinish2 = () => {
    setSubmitButtonDisabled(false);
  };
  const onResizeFinish3 = () => {
    setSubmitButtonDisabled(false);
  };

  return (
    <>
      <form
        onSubmit={onSubmit}
        style={{ margin: '10px', padding: '10px', border: 'solid 1px black' }}
      >
        <div style={{ display: 'flex' }}>
          <div style={{ maxWidth: '200px', margin: '10px' }}>
            <label htmlFor="id_comment1">Comment</label>
            <input
              type="text"
              id="id_comment1"
              value={comment1}
              onChange={e => setComment1(e.target.value)}
            />
            <br />
            <br />
            <ImageS3Upload
              signingUrl={URL_GENERATE_S3_URLKEY}
              autoUpload={false}
              serverPhoto={SERVER_PHOTO}
              resizer={resizerOptions}
              onResizeStart={onResizeStart1}
              onResizeFinish={onResizeFinish1}
              ref={refS3Uploader1}
              value={imageS3URL1}
              onChange={(e: any) => setImageS3URL1(e.target.value)}
            />
          </div>

          <div style={{ maxWidth: '200px', margin: '10px' }}>
            <label htmlFor="id_comment4">Comment</label>
            <input
              type="text"
              id="id_comment4"
              value={comment2}
              onChange={e => setComment2(e.target.value)}
            />
            <br />
            <br />
            <ImageS3Upload
              signingUrl={URL_GENERATE_S3_URLKEY}
              autoUpload={false}
              serverPhoto={SERVER_PHOTO}
              resizer={resizerOptions}
              onResizeStart={onResizeStart2}
              onResizeFinish={onResizeFinish2}
              ref={refS3Uploader2}
              value={imageS3URL2}
              onChange={(e: any) => setImageS3URL2(e.target.value)}
            />
          </div>

          <div style={{ maxWidth: '200px', margin: '10px' }}>
            <label htmlFor="id_comment5">Comment</label>
            <input
              type="text"
              id="id_comment5"
              value={comment3}
              onChange={e => setComment3(e.target.value)}
            />
            <br />
            <br />
            <ImageS3Upload
              signingUrl={URL_GENERATE_S3_URLKEY}
              autoUpload={false}
              serverPhoto={SERVER_PHOTO}
              resizer={resizerOptions}
              onResizeStart={onResizeStart3}
              onResizeFinish={onResizeFinish3}
              ref={refS3Uploader3}
              value={imageS3URL3}
              onChange={(e: any) => setImageS3URL3(e.target.value)}
            />
          </div>
        </div>
        <input
          type="submit"
          value="Submit"
          style={{ width: '100%' }}
          className="button"
          disabled={submitButtonDisabled}
        ></input>
      </form>
    </>
  );
}

export default App;

Example 5

Multiple components in one form autoUpload=True

import React, { useState, useRef, useEffect } from 'react';
import { ImageS3Upload } from 'react-image-upload-s3';

function App() {
  const URL_GENERATE_S3_URLKEY = 'https://yourserver.com/s3/sign/';
  const SERVER_PHOTO = 'https://example.amazonaws.com/';

  const resizerOptions = {
    enabled: true,
    autoResize: true, // otherwise resizing will be preform before uploading
    maxWidth: 1280,
    maxHeight: 1280,
    compressFormat: 'JPEG',
    quality: 70,
    rotation: 0,
  };

  const [uploadStatus, setUploadStatus] = useState({
    image1: true,
    image2: true,
    image3: true,
  });

  const [comment1, setComment1] = useState('');
  const [comment2, setComment2] = useState('');
  const [comment3, setComment3] = useState('');
  const [imageS3URL1, setImageS3URL1] = useState('');
  const [imageS3URL2, setImageS3URL2] = useState('');
  const [imageS3URL3, setImageS3URL3] = useState('');

  const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);

  useEffect(() => {
    if (uploadStatus.image1 && uploadStatus.image2 && uploadStatus.image3) {
      setSubmitButtonDisabled(false);
    } else {
      setSubmitButtonDisabled(true);
    }
  }, [uploadStatus]);

  const onSubmit = async (e: any) => {
    e.preventDefault();
    const data = {
      comment1: comment1,
      image1: imageS3URL1,
      comment2: comment2,
      image2: imageS3URL2,
      comment3: comment3,
      image3: imageS3URL3,
    };
    console.log('submitedData', data);
  };

  const onStart1 = () => {
    setUploadStatus((prev: any) => ({ ...prev, image1: false }));
  };

  const onStart2 = () => {
    setUploadStatus((prev: any) => ({ ...prev, image2: false }));
  };

  const onStart3 = () => {
    setUploadStatus((prev: any) => ({ ...prev, image3: false }));
  };

  const onFinish1 = (isSuccessful: boolean) => {
    setUploadStatus((prev: any) => ({ ...prev, image1: true }));
  };

  const onFinish2 = (isSuccessful: boolean) => {
    setUploadStatus((prev: any) => ({ ...prev, image2: true }));
  };

  const onFinish3 = (isSuccessful: boolean) => {
    setUploadStatus((prev: any) => ({ ...prev, image3: true }));
  };

  return (
    <>
      <form
        onSubmit={onSubmit}
        style={{ margin: '10px', padding: '10px', border: 'solid 1px black' }}
      >
        <div style={{ display: 'flex' }}>
          <div style={{ maxWidth: '200px', margin: '10px' }}>
            <label htmlFor="id_comment1">Comment</label>
            <input
              type="text"
              id="id_comment1"
              value={comment1}
              onChange={e => setComment1(e.target.value)}
            />
            <br />
            <br />
            <ImageS3Upload
              signingUrl={URL_GENERATE_S3_URLKEY}
              autoUpload={true}
              serverPhoto={SERVER_PHOTO}
              onStart={onStart1}
              onFinish={onFinish1}
              resizer={resizerOptions}
              value={imageS3URL1}
              onChange={e => setImageS3URL1(e.target.value)}
            />
          </div>

          <div style={{ maxWidth: '200px', margin: '10px' }}>
            <label htmlFor="id_comment2">Comment</label>
            <input
              type="text"
              id="id_comment2"
              value={comment2}
              onChange={e => setComment2(e.target.value)}
            />
            <br />
            <br />
            <ImageS3Upload
              signingUrl={URL_GENERATE_S3_URLKEY}
              autoUpload={true}
              serverPhoto={SERVER_PHOTO}
              onStart={onStart2}
              onFinish={onFinish2}
              resizer={resizerOptions}
              value={imageS3URL2}
              onChange={e => setImageS3URL2(e.target.value)}
            />
          </div>

          <div style={{ maxWidth: '200px', margin: '10px' }}>
            <label htmlFor="id_comment3">Comment</label>
            <input
              type="text"
              id="id_comment3"
              value={comment3}
              onChange={e => setComment3(e.target.value)}
            />
            <br />
            <br />
            <ImageS3Upload
              signingUrl={URL_GENERATE_S3_URLKEY}
              autoUpload={true}
              serverPhoto={SERVER_PHOTO}
              onStart={onStart3}
              onFinish={onFinish3}
              resizer={resizerOptions}
              value={imageS3URL3}
              onChange={e => setImageS3URL3(e.target.value)}
            />
          </div>
        </div>
        <input
          type="submit"
          value="Submit"
          style={{ width: '100%' }}
          className="button"
          disabled={submitButtonDisabled}
        ></input>
      </form>
    </>
  );
}

export default App;

Options

| Option | Description | Type | Required | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -------- | | signingUrl | To receive a presigned URL. | string | Yes | | autoUpload | Whether an image will be upload immediately, otherwise you should call a method refImageS3Upload.current.uploadFile() to start uploading. | boolean | Yes | | serverPhoto | S3 storage Service endpoints. For example: https://bucket_name.s3.us-east-2.amazonaws.com/ | string | No | | emptyPhoto | You can change a default empty background. | string | No | | buttonCaption | You can change caption on the button. The default value is 'Browse...' | string | No | | showSize | Wether to show file size after resizing on the button. The default value is True | boolean | No | | value | Value of component (file name) | string | No | | resizer | See Resizer options section. | object | No | | uploadFile | Method to start uploading: () => Promise | method | | | onStart | () => void | function | No | | onFinish | (isSuccessful: boolean, urlImage: string) => void | function | No | | onUploaded | () => void | function | No | | onProgress | (percent: number) => void | function | No | | onResizeStart | () => void | function | No | | onResizeFinish | () => void | function | No | | onSignedUrl | (data: any) => void | function | No | | onError | (msg: string) => void | function | No |

Resizer options

| Option | Description | Type | Required | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -------- | | enabled | Whether the resizer is enabled or disabled. | boolean | Yes | | autoResize | Start the process of resizing immediately after selecting the file, otherwise resizing will be preform before uploading, the parametr doesn't make sense if autoUpload = True | boolean | Yes | | maxWidth | New image max width (ratio is preserved) | number | Yes | | maxHeight | New image max height (ratio is preserved) | number | Yes | | compressFormat | Can be either JPEG, PNG or WEBP. | string | Yes | | quality | A number between 0 and 100. Used for the JPEG compression.(if no compress is needed, just set it to 100) | number | Yes | | rotation | Degree of clockwise rotation to apply to the image. Rotation is limited to multiples of 90 degrees.(if no rotation is needed, just set it to 0) (0, 90, 180, 270, 360) | number | Yes |

License

MIT