Uppy: How to style FileInput

Created on 7 May 2018  路  6Comments  路  Source: transloadit/uppy

Is there a way to apply custom styles to the FileInput plugin? It would be nice to pass your own CSS classes. Better still, we can hide the input and use trigger option. Unless there is already a way and I missing something?

Of course, we can manually override the CSS classes, but that's not ideal.

File Input Improvement Question

Most helpful comment

Another way is to use fineuploader's approach to make the file input invisible but clickable.

// set file input target
// pretty must be true for this css modification
uppy.use(FileInput, { target: '.upload-btn', pretty: true})
// html elements
<button class="upload-btn">
  <div class="btn-icon"><span class="fa fa-camera"/></div
  <div class="btn-text">Upload</div
</button>

On HTML display, this is what uppy renders

<button class="upload-btn">
  <div class="btn-icon"><span class="fa fa-camera"/></div
  <div class="btn-text">Upload</div>

  <div class="uppy-Root uppy-FileInput-container">
    <input class="uppy-FileInput-input" type="file" name="files[]" multiple="" accept="image/jpg,image/jpeg,image/png" style="width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1;">
    <button class="uppy-FileInput-btn" type="button">Choose files</button>
  </div>
</button>

Just add the following css and you can trigger upload with your own upload button

// add css
.upload-btn {
    position: relative;
    overflow: hidden;

    button.uppy-FileInput-btn {
        position: absolute;
        right: 0px;
        top: 0px;
        margin: 0px;
        padding: 0px;
        cursor: pointer;
        opacity: 0;
        height: 100%;
        width: 100%;
    }
}

All 6 comments

Yeah, that鈥檚 the reason we are keeping css classes accessible, to allow for easy overrides. I think in case of FileInput, an options object with styles that will be set inline might be a good idea 馃

If you are going to hide it and trigger from your own input/button, you might as well re-implement it and call uppy.addFile() in event callback?

https://github.com/transloadit/uppy/blob/0337b09385fd4ec974703d28a6708d6f895e4cdc/src/plugins/FileInput.js#L43-L56

Another way is to use fineuploader's approach to make the file input invisible but clickable.

// set file input target
// pretty must be true for this css modification
uppy.use(FileInput, { target: '.upload-btn', pretty: true})
// html elements
<button class="upload-btn">
  <div class="btn-icon"><span class="fa fa-camera"/></div
  <div class="btn-text">Upload</div
</button>

On HTML display, this is what uppy renders

<button class="upload-btn">
  <div class="btn-icon"><span class="fa fa-camera"/></div
  <div class="btn-text">Upload</div>

  <div class="uppy-Root uppy-FileInput-container">
    <input class="uppy-FileInput-input" type="file" name="files[]" multiple="" accept="image/jpg,image/jpeg,image/png" style="width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1;">
    <button class="uppy-FileInput-btn" type="button">Choose files</button>
  </div>
</button>

Just add the following css and you can trigger upload with your own upload button

// add css
.upload-btn {
    position: relative;
    overflow: hidden;

    button.uppy-FileInput-btn {
        position: absolute;
        right: 0px;
        top: 0px;
        margin: 0px;
        padding: 0px;
        cursor: pointer;
        opacity: 0;
        height: 100%;
        width: 100%;
    }
}

Another way is to use fineuploader's approach to make the file input invisible but clickable.

// set file input target
// pretty must be true for this css modification
uppy.use(FileInput, { target: '.upload-btn', pretty: true})
// html elements
<button class="upload-btn">
  <div class="btn-icon"><span class="fa fa-camera"/></div
  <div class="btn-text">Upload</div
</button>

On HTML display, this is what uppy renders

<button class="upload-btn">
  <div class="btn-icon"><span class="fa fa-camera"/></div
  <div class="btn-text">Upload</div>

  <div class="uppy-Root uppy-FileInput-container">
    <input class="uppy-FileInput-input" type="file" name="files[]" multiple="" accept="image/jpg,image/jpeg,image/png" style="width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1;">
    <button class="uppy-FileInput-btn" type="button">Choose files</button>
  </div>
</button>

Just add the following css and you can trigger upload with your own upload button

// add css
.upload-btn {
    position: relative;
    overflow: hidden;

    button.uppy-FileInput-btn {
        position: absolute;
        right: 0px;
        top: 0px;
        margin: 0px;
        padding: 0px;
        cursor: pointer;
        opacity: 0;
        height: 100%;
        width: 100%;
    }
}

use this hidden but clickable idea to wrap a React version fileInput works really well.

/**
 * there is no React version FileInput in Uppy but similar Component <DragDrop>
 * below code refer to
 * https://github.com/transloadit/uppy/blob/master/packages/%40uppy/react/src/DragDrop.js
 * https://github.com/transloadit/uppy/issues/813#issuecomment-494348650
 * https://stackoverflow.com/a/27564324/6414615
 *
 */
import React from 'react';
import PropTypes from 'prop-types';
import FileInput from '@uppy/file-input';
import _omit from 'lodash/omit';

// comment due to custimization style
// import '@uppy/file-input/dist/style.min.css';

const h = React.createElement;

/**
 * React component that renders an area in which files can be dropped to be
 * uploaded.
 */

class UppyInput extends React.Component {
  componentDidMount() {
    this.installPlugin();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.uppy !== this.props.uppy) {
      this.uninstallPlugin(prevProps);
      this.installPlugin();
    }
  }

  componentWillUnmount() {
    this.uninstallPlugin();
  }

  installPlugin() {
    const uppy = this.props.uppy;
    const options = Object.assign({ id: 'react:FileInput' }, this.props, {
      target: this.container,
      ..._omit(this.props, ['component', 'uppy']),
    });
    delete options.uppy;

    uppy.use(FileInput, options);

    this.plugin = uppy.getPlugin(options.id);
  }

  uninstallPlugin(props = this.props) {
    const uppy = props.uppy;

    uppy.removePlugin(this.plugin);
  }

  render() {
    return (
      <div style={{ position: 'relative', display: 'inline-block' }}>
        <style>
          {`
            div.uppy-FileInput-container{
                width: 100%;
                height: 100%;
                position: absolute;
                top: 0;
                left: 0;
                opacity: 0;
             }
            button.uppy-FileInput-btn{
                width: 100%;
                height: 100%;
            }

        `}
        </style>
        <div
          ref={ref => {
            if (ref) {
              this.container = ref;
            }
          }}
        />
        {this.props.component}
      </div>
    );
  }
}

UppyInput.propTypes = {
  component: PropTypes.elementType.isRequired,
};

export default UppyInput;

Is there a way to trigger the file picker with js and then send the selected files to Uppy? Thx

Is there a way to trigger the file picker with js and then send the selected files to Uppy? Thx

Yes, you can set an oninput event on an input and then do document.querySelector('.someInput').click(), and then uppy.addFile({ data: fileThatWasSelected, name: 'fileName' }). See addFile docs.

Ty!

Was this page helpful?
0 / 5 - 0 ratings