carbon-design-system / carbon-components-svelte

Svelte implementation of the Carbon Design System
https://svelte.carbondesignsystem.com
Apache License 2.0
2.65k stars 256 forks source link

FileUploader with preview using ImageLoader? #693

Open ricardo-valero opened 3 years ago

ricardo-valero commented 3 years ago

Hi, does anyone know how to create a file preview using carbon components?

https://codesandbox.io/s/fileuploader-with-preview-attempt-v88vp

<script>
import {
    FileUploader,
    ImageLoader,
    InlineLoading
} from "carbon-components-svelte";
let files = [];
let image;
function previewImage(e) {
    image = URL.createObjectURL(e.target.files[0]);
}
</script>

<ImageLoader src={image}>
  <div slot="loading">
    <InlineLoading />
  </div>
  <div slot="error">An error occurred.</div>
</ImageLoader>
<FileUploader
  buttonLabel="Upload image"
  accept={['.jpg', '.jpeg', '.png']}
  bind:files
  on:change={previewImage}
  status="complete"
/>

Using the img tag works fine, but I'd appreciate some insight.

arekbal commented 3 years ago
  1. When using URL.createObjectURL API remember to call URL.revokeObjectURL() at some point in component lifecycle or during image replacement. There is alternative strictly Base64 API but it takes a considerable more memory.
  2. Most of the time you upload image for display, not only to store it for sharing or later. In order to do so effectively, crop functionality is almost a must - most of the time.
  3. Because these images are often a photo, orientation metadata gets messed up often(jpg exif metadata extension) and image uploaded vertically could show in reverse or on a side, so handling this for display might be a requirement as well. There are libs that do strictly that.
  4. Enabling users to rotate the image manually before images get uploaded might be useful for some pictures taken from the top or in strange angles.
  5. Then the issue of pixel resolution/file size limit comes in and possible in-browser re-scaling in case it's too big, but it's a bit harder to do this good than it sounds. There are libs that do strictly that.

But treat steps 2-5 as optional. Just make sure that your component enables someone to extend your component with such steps.