File uploader

Account photo

Only .jpg and .png files. 500kb max file size.

Code:
<!--
  Copyright IBM Corp. 2016, 2018

  This source code is licensed under the Apache-2.0 license found in the
  LICENSE file in the root directory of this source tree.
-->

<div class="bx--form-item">
  <strong class="bx--file--label">Account
    photo</strong>
  <p class="bx--label-description">Only .jpg and .png files. 500kb max file size.</p>
  <div class="bx--file" data-file>
    <label for="your-file-importer-id-here"
      class="bx--file-btn bx--btn bx--btn--primary"
      role="button" tabindex="0">Add file</label>
    <input type="file" class="bx--file-input" id="your-file-importer-id-here" data-file-uploader
      data-target="[data-file-container]" multiple />
    <div data-file-container class="bx--file-container">
    </div>
  </div>
</div>

Upload states

Account photo

Only .jpg and .png files. 500kb max file size.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero vero sapiente illum reprehenderit molestiae perferendis voluptatem temporibus laudantium ducimus magni voluptatum veniam, odit nesciunt corporis numquam maxime sunt excepturi sint!

color.jpeg

File size exceeds limit

color.jpeg

Vanilla JS
Code:
<!--
  Copyright IBM Corp. 2016, 2018

  This source code is licensed under the Apache-2.0 license found in the
  LICENSE file in the root directory of this source tree.
-->

<div class="bx--form-item">
  <strong class="bx--file--label">Account
    photo</strong>
  <p class="bx--label-description">Only .jpg and .png files. 500kb max file size.</p>
  <div class="bx--file" data-file>
    <label for="your-file-importer-id-here"
      class="bx--file-btn bx--btn bx--btn--primary"
      role="button" tabindex="0">Add file</label>
    <input type="file" class="bx--file-input" id="your-file-importer-id-here" data-file-uploader
      data-target="[data-file-container]" multiple />
    <div data-file-container class="bx--file-container">
      <div class="bx--file__selected-file">
        <p class="bx--file-filename">Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero vero
          sapiente illum reprehenderit molestiae perferendis voluptatem temporibus laudantium ducimus magni voluptatum
          veniam, odit nesciunt corporis numquam maxime sunt excepturi sint!</p>
        <span data-for="your-file-importer-id-here" class="bx--file__state-container">
          <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" class="bx--file-complete" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 1C4.1 1 1 4.1 1 8s3.1 7 7 7 7-3.1 7-7-3.1-7-7-7zM7 11L4.3 8.3l.9-.8L7 9.3l4-3.9.9.8L7 11z"></path><path d="M7 11L4.3 8.3l.9-.8L7 9.3l4-3.9.9.8L7 11z" data-icon-path="inner-path" opacity="0"></path></svg>
        </span>
      </div>
      <div class="bx--file__selected-file--invalid__wrapper">
        <div class="bx--file__selected-file bx--file__selected-file--invalid" data-invalid>
          <p class="bx--file-filename">color.jpeg</p>
          <span data-for="your-file-importer-id-here" class="bx--file__state-container">
            <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" class="bx--file--invalid" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 1C4.2 1 1 4.2 1 8s3.2 7 7 7 7-3.1 7-7-3.1-7-7-7zm-.5 3h1v5h-1V4zm.5 8.2c-.4 0-.8-.4-.8-.8s.3-.8.8-.8c.4 0 .8.4.8.8s-.4.8-.8.8z"></path><path d="M7.5 4h1v5h-1V4zm.5 8.2c-.4 0-.8-.4-.8-.8s.3-.8.8-.8c.4 0 .8.4.8.8s-.4.8-.8.8z" data-icon-path="inner-path" opacity="0"></path></svg>
            <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" class="bx--file--close" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path d="M12 4.7l-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8z"></path></svg>
          </span>
        </div>
        <div class="bx--form-requirement">
          File size exceeds limit
        </div>
      </div>
      <div class="bx--file__selected-file">
        <p class="bx--file-filename">color.jpeg</p>
        <span data-for="your-file-importer-id-here" class="bx--file__state-container">
          <div class="bx--inline-loading__animation">
            <div data-inline-loading-spinner="" class="bx--loading bx--loading--small">
              <svg class="bx--loading__svg" viewBox="-75 -75 150 150">
                <circle class="bx--loading__background" cx="0" cy="0" r="37.5"></circle>
                <circle class="bx--loading__stroke" cx="0" cy="0" r="37.5"></circle>
              </svg>
            </div>
          </div>
        </span>
      </div>
    </div>
  </div>
</div>

Documentation

JavaScript

Getting component class reference

ES2015
import { FileUploader } from 'carbon-components';
With pre-build bundle (carbon-components.min.js)
var FileUploader = CarbonComponents.FileUploader;

Instantiating

// `#my-file` is an element with `[data-file]` attribute
FileUploader.create(document.getElementById('my-file'));

Public Methods

Name Params Description
setState state: String, selectIndex: Number After files are added, call this method to change state of the filenames ('upload', 'complete', 'edit').
release Deletes the instance
Example - Changing the uploading state
// `#my-file` is an element with `[data-file]` attribute
var fileUploaderInstance = FileUploader.create(
  document.getElementById('my-file')
);
// Makes the 2nd file shown as its uploading complete
fileUploaderInstance.setState('complete', 1);

Options

Option Default Selector Description
selectorInit [data-file] Element for initializing instance
selectorInput [input[type="file"].bx--file-input] Input element
selectorContainer [data-file-container] Element for injecting HTML for upload and edit states
selectorCloseButton .bx--file-close Close button for removing filename nodes

Events

Event Name Description
change When files are added to File Uploader, a change event is fired. This also triggers custom events; see eventBeforeDisplayFilesFileuploader and eventAfterDisplayFilesFileuploader`
eventBeforeDeleteFilenameFileuploader Triggered before clicking on close button(s) inside filename node(s).
eventAfterDeleteFilenameFileuploader Triggered after clicking on close button(s) inside filename node(s).

FAQ

Using and understanding File Uploader

When files are added to File Uploader, a change event is fired. The change event triggers a private method to inject HTML into the selectorContainer element displaying all added filenames.

file

Trigger additional states using setState() public method. Additional states are edit, complete and upload.

Edit injects close icons into each filename state container. A click event listener is also added to remove the filename when close button is clicked.

edit

.bx--file__state-container .bx--file-close {
  width: 1rem;
  height: 1rem;
  fill: $text-01;
  cursor: pointer;
}

Upload injects Loading components into each filename state container.

Developers using File Uploader will be able to use JavaScript to inject a Loading component when selected files are actually being uploaded. Users can select a single file or multiple files. By default, any file type is accepted. It's up to the developer and their design team to specify and implement validations for which file types are acceptable.

upload

Complete injects checkmark icons into each filename state container.

complete

.bx--loading {
  width: 2rem;
  height: 2rem;
  margin-right: -7px;
}
.bx--loading__svg {
  stroke: $ui-05;
}

WCAG AA Color Accessibility

File Uploader color contrast ratios are accessible. Since File Uploader (specifically filename elements) low-opacity colors, verifying color ratios with IBM a11y tool may not yield passing results.

However, evaluating resulting background colors as solid colors will pass.

Opacity + UI background color Actual background color Text color WCAG AA Color Ratio Passes 4.5?
#5a6872 at 10% on #ffffff #cedbec #152935 10.70 :white_check_mark:
#5a6872 at 10% on #f5f7fa #c6d5e8 #152935 10.07 :white_check_mark:

Truncating long filenames

By default, filenames are truncated so that any filename that goes beyond 300px will be cutoff.

image

Truncating filenames is enabled through the use of @mixin text-overflow($size).

You can override this behavior with SCSS by giving the @mixin a new width by overriding this @mixin.

// Using mixin, override initial styles in _file-uploader.scss
.bx--file-filename {
  @include text-overflow(768px);
}

You can also use plain CSS by setting a new width.

.bx--file-filename {
  width: 768px;
}