Light Dark System

File Upload

<p-file-upload> | PFileUpload
Since 2.0 experimental

File Upload provides an area where files can be dragged and dropped onto from the Operating System to be uploaded or to be used for other tasks. It also provides a button to open a file dialog and select files from the file system. Per default the File Dropzone shows a list of all selected files below the dropzone.

Click to upload or drag and drop
<p-file-upload closable multiple
  label="Support for uploading single files or in bulk, including JPG, JPEG, and PNG formats"
>
  <span slot="button">
    <p-button variant="text">
      <span style="font-weight: 600;">Click to upload</span>
      <span style="font-weight: 400; color: #475467;">or drag and drop</span>
    </p-button>
  </span>
</p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload closable multiple></PFileUpload>;

Examples

Disabled

Set the disabled attribute to disable the element.

<p-file-upload disabled></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload disabled></PFileUpload>;

Hide Button

Set the no-button attribute to hide the button in the dropzone.

<p-file-upload no-button></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload no-button></PFileUpload>;

Button Only

Set the button-only attribute to show only a file input button instead of a dropzone.

<p-file-upload button-only></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload button-only></PFileUpload>;

Customizing Labels

Set the label and button-label attribute to override the default labels.

<p-file-upload
  label="Please combine all documents into one PDF file. The maximum file size is 3MB."
  button-label="Upload your CV or Resume"
></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => (
  <PFileUpload
    label="Please combine all documents into one PDF file. The maximum file size is 3MB."
    button-label="Upload your CV or Resume"
  ></PFileUpload>
);

Customizing Button

Use the button slot to customize the button appearance.

Custom Button
<p-file-upload>
  <p-button variant="danger" slot="button"> Custom Button </p-button>
</p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => (
  <PFileUpload
    label="Please combine all documents into one PDF file. The maximum file size is 3MB."
    button-label="Upload your CV or Resume"
  ></PFileUpload>
);

No File List

Set the no-file-list attribute to hide the file list.

<p-file-upload no-file-list></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload no-file-list></PFileUpload>;

Maximum File Size

Set the max-file-size attribute to set a maximum file size limit. The user will receive a warning, when the selected file is too large.

<p-file-upload max-file-size="100"></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload max-file-size={100}></PFileUpload>;

Maximum Number of Files

Set the max-files attribute to limit the number of files that can be added. Only works together with the multiple attribute.

<p-file-upload max-files="2" multiple></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload max-files={2} multiple></PFileUpload>;

Accepted File Types

Set the accept attribute to set the accepted MIME-Type of the files. This attribute is consistent with the native file input. Visit the MDN documentation for the accept attribute for more information.

<p-file-upload accept="image/*"></p-file-upload>
import { PFileUpload } from 'pure-uikit/dist/react';

const App = () => <PFileUpload accept="image/*"></PFileUpload>;

Form Usage with FormData

The FileUpload component can be used inside a form as a replacement for <input type="file">. The files can be accessed using FormData. See Form Control documentation for more details.



Reset Submit
<form class="file-upload">
  <p-file-upload name="p-file-upload" no-button multiple></p-file-upload>
  <br />
  <input type="file" name="native-input" multiple></input>
  <br />
  <p-button type="reset" variant="default">Reset</p-button>
  <p-button type="submit" variant="primary">Submit</p-button>
</form>

<script type="module">
  const form = document.querySelector('.file-upload');
  form.addEventListener('submit', event => {
    event.preventDefault();
    const formData = new FormData(form);
    console.log(formData.getAll('native-input'), formData.getAll('p-file-upload'));
  });
</script>
import { useRef } from 'react';
import { PFileUpload, PButton } from 'pure-uikit/dist/react';

const App = () => {
  const form = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    const formData = new FormData(form);
    console.log(formData.getAll('native-input'), formData.getAll('p-file-upload'));
  }

  return (
    <form onSubmit={handleSubmit} ref={form}>
      <PFileUpload name="p-file-upload" no-button multiple></PFileUpload>
      <br />
      <input type="file" name="native-input" multiple></input>
      <br />
      <PButton type="reset" variant="default">
        Reset
      </PButton>
      <PButton type="submit" variant="primary">
        Submit
      </PButton>
    </form>
  );
};

Form Usage with JSON

The FileUpload component can be used inside a form as a replacement for <input type="file">. The files can be serialized using JSON. See Form Control documentation for more details.



Reset Submit
<form class="file-upload-json">
  <p-file-upload name="p-file-upload" no-button multiple></p-file-upload>
  <br />
  <input type="file" name="native-input" multiple></input>
  <br />
  <p-button type="reset" variant="default">Reset</p-button>
  <p-button type="submit" variant="primary">Submit</p-button>
</form>

<script type="module">
  import { serialize } from '../dist/utilities/form.js';
  const form = document.querySelector('.file-upload-json');
  form.addEventListener('submit', event => {
    event.preventDefault();
    const data = serialize(form);
    console.log(data);
  });
</script>
import { useRef } from 'react';
import { PFileUpload, PButton } from 'pure-uikit/dist/react';
import { serialize } from '../dist/utilities/form.js';

const App = () => {
  const form = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    const data = serialize(form);
    console.log(data);
  }

  return (
    <form onSubmit={handleSubmit} ref={form}>
      <PFileUpload name="p-file-upload" no-button multiple></PFileUpload>
      <br />
      <input type="file" name="native-input" multiple></input>
      <br />
      <PButton type="reset" variant="default">
        Reset
      </PButton>
      <PButton type="submit" variant="primary">
        Submit
      </PButton>
    </form>
  );
};

Upload Files

To upload a file, listen to the p-change event and handle the received file. This example uses XMLHttpRequest, but the same could be achieved with axios or the fetch API.

<p-file-upload class="upload-file"></p-file-upload>

<script type="module">
  const fileUpload = document.querySelector('.upload-file');
  fileUpload.addEventListener('p-change', event => {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://localhost:8080');
    xhr.setRequestHeader('Content-Type', fileInfo.file.type);
    xhr.send(fileInfo.file);
  });
</script>
import { useRef } from 'react';
import { PFileUpload, PButton } from 'pure-uikit/dist/react';
import { serialize } from '../dist/utilities/form.js';

const App = () => {
  const form = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://localhost:8080');
    xhr.setRequestHeader('Content-Type', fileInfo.file.type);
    xhr.send(fileInfo.file);
  }

  return (
    <form onSubmit={handleSubmit} ref={form}>
      <PFileUpload name="p-file-upload"></PFileUpload>
      <br />
      <input type="file" name="native-input"></input>
      <br />
      <PButton type="reset" variant="default">
        Reset
      </PButton>
      <PButton type="submit" variant="primary">
        Submit
      </PButton>
    </form>
  );
};

Upload Files and indicate loading

Set loading to true on the FileInfo object to add a loading indicator to the FileUploadItem.

<p-file-upload class="upload-file-loading"></p-file-upload>

<script type="module">
  const fileUpload = document.querySelector('.upload-file-loading');
  fileUpload.addEventListener('p-change', async event => {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://localhost:8080/upload/');
    xhr.setRequestHeader('Content-Type', fileInfo.file.type);
    xhr.send(fileInfo.file);
    fileInfo.loading = true;
    setTimeout(() => {
      fileInfo.loading = false;
      fileUpload.requestUpdate();
    }, 3000);
  });
</script>
import { useRef } from 'react';
import { PFileUpload, PButton } from 'pure-uikit/dist/react';
import { serialize } from '../dist/utilities/form.js';

const App = () => {
  const form = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://localhost:8080');
    xhr.setRequestHeader('Content-Type', fileInfo.file.type);
    xhr.send(fileInfo.file);

    fileInfo.loading = true;

    setTimeout(() => {
      fileInfo.loading = false;
      fileUpload.requestUpdate();
    }, 3000);
  }

  return (
    <form onSubmit={handleSubmit} ref={form}>
      <PFileUpload name="p-file-upload"></PFileUpload>
      <br />
      <input type="file" name="native-input"></input>
      <br />
      <PButton type="reset" variant="default">
        Reset
      </PButton>
      <PButton type="submit" variant="primary">
        Submit
      </PButton>
    </form>
  );
};

Upload Files and handling Errors

To handle errors in a XMLHttpRequest the upload.onerror callback can be used.

<p-file-upload class="upload-file-errors"></p-file-upload>

<script type="module">
  const fileUpload = document.querySelector('.upload-file-errors');
  fileUpload.addEventListener('p-change', async event => {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();
    xhr.upload.onerror = event => {
      console.error('error:', event);
      fileInfo.loading = false;
      fileInfo.warning = 'Upload Failed';
      fileInfo.accepted = false;
      fileUpload.requestUpdate();
    };
    xhr.open('POST', 'http://localhost');
    xhr.setRequestHeader('Content-Type', fileInfo.file.type);
    xhr.send(fileInfo.file);
    fileInfo.loading = true;
  });
</script>
import { useRef } from 'react';
import { PFileUpload, PButton } from 'pure-uikit/dist/react';
import { serialize } from '../dist/utilities/form.js';

const App = () => {
  const form = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();

    xhr.upload.onerror = event => {
      console.error('error:', event);
      fileInfo.loading = false;
      fileInfo.warning = 'Upload Failed';
      fileInfo.accepted = false;

      fileUpload.requestUpdate();
    };

    xhr.open('POST', 'http://localhost');
    xhr.setRequestHeader('Content-Type', fileInfo.file.type);
    xhr.send(fileInfo.file);

    fileInfo.loading = true;
  }

  return (
    <form onSubmit={handleSubmit} ref={form}>
      <PFileUpload name="p-file-upload"></PFileUpload>
      <br />
      <input type="file" name="native-input"></input>
      <br />
      <PButton type="reset" variant="default">
        Reset
      </PButton>
      <PButton type="submit" variant="primary">
        Submit
      </PButton>
    </form>
  );
};

Upload Files and update progress

The XMLHttpRequest provides an upload.onprogress callback that can be used to change the progress attribute on the FileInfo object.

<p-file-upload class="upload-file-progress"></p-file-upload>

<script type="module">
  const fileUpload = document.querySelector('.upload-file-progress');
  fileUpload.addEventListener('p-change', async event => {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();
    xhr.upload.onprogress = event => {
      if (event.lengthComputable) {
        console.log('progress: ', (event.loaded / event.total) * 100);
        fileInfo.progress = (event.loaded / event.total) * 100;
        fileUpload.requestUpdate();
      }
    };
    xhr.upload.onload = event => {
      console.log('complete: ', event);
      fileInfo.loading = false;
      fileUpload.requestUpdate();
    };
    xhr.open('POST', 'http://localhost:8080/upload');
    var formData = new FormData();
    formData.append('file', fileInfo.file);
    xhr.send(formData);
    fileInfo.loading = true;
  });
</script>
import { useRef } from 'react';
import { PFileUpload, PButton } from 'pure-uikit/dist/react';
import { serialize } from '../dist/utilities/form.js';

const App = () => {
  const form = useRef(null);

  function handleSubmit(event) {
    event.preventDefault();
    const fileInfo = event.detail?.[0];
    const xhr = new XMLHttpRequest();

    xhr.upload.onprogress = event => {
      if (event.lengthComputable) {
        console.log('progress: ', (event.loaded / event.total) * 100);
        fileInfo.progress = (event.loaded / event.total) * 100;
        fileUpload.requestUpdate();
      }
    };

    xhr.upload.onload = event => {
      console.log('complete: ', event);
      fileInfo.loading = false;
      fileUpload.requestUpdate();
    };

    xhr.open('POST', 'http://localhost:8080/upload');
    var formData = new FormData();
    formData.append('file', fileInfo.file);
    xhr.send(formData);

    fileInfo.loading = true;
  }

  return (
    <form onSubmit={handleSubmit} ref={form}>
      <PFileUpload name="p-file-upload"></PFileUpload>
      <br />
      <input type="file" name="native-input"></input>
      <br />
      <PButton type="reset" variant="default">
        Reset
      </PButton>
      <PButton type="submit" variant="primary">
        Submit
      </PButton>
    </form>
  );
};

Custom Image

Set the image slot to customize the appearance of the image within the dropzone.

<p-file-upload>
  <p-qr-code slot="image" value="https://pureui.xyz/"></p-qr-code>
</p-file-upload>
import { PFileUpload, PQrCode } from 'pure-uikit/dist/react';

const App = () => (
  <PFileUpload>
    <PQrCode slot="image" value="https://pureui.xyz/" />;
  </PFileUpload>
);

Custom Content

Set the content slot to customize the appearance of the dropzone.

This card is a dropzone. You can drag all sorts of things in it!
Footer
<p-file-upload>
  <p-card slot="label" class="card-footer">
    This card is a dropzone. You can drag all sorts of things in it!
    <div slot="footer">Footer</div>
  </p-card>
</p-file-upload>

<style>
  .card-footer {
    max-width: 300px;
  }
  .card-footer [slot='footer'] {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
</style>
import { PFileUpload, PCard, PRating } from 'pure-uikit/dist/react';

const css = `
  .card-footer {
    max-width: 300px;
  }
  .card-footer [slot="footer"] {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
`;

const App = () => (
  <>
    <PFileUpload>
      <PCard slot="content" className="card-footer">
        This card is a dropzone. You can drag all sorts of things in it!
        <div slot="footer">
          <PRating></PRating>
        </div>
      </PCard>
    </PFileUpload>

    <style>{css}</style>
  </>
);

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/pure-uikit@1.3.13/cdn/components/file-upload/file-upload.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/pure-uikit@1.3.13/cdn/components/file-upload/file-upload.js';

To import this component using a bundler:

import 'pure-uikit/dist/components/file-upload/file-upload.js';

To import this component as a React component:

import PFileUpload from 'pure-uikit/dist/react/file-upload';

Slots

Name Description
label The dropzone’s label. Alternatively, you can use the image slot and label prop.
image The dropzone’s image.
button The dropzone’s button.

Learn more about using slots.

Properties

Name Description Reflects Type Default
warning Internal property to show a warning in the dropzone string | undefined -
isDragover Indicates whether a file is currently dragged over the dropzone boolean false
name The input’s name attribute. string -
disabled Disables the dropzone. boolean false
noButton
no-button
If true, hides button to open the native file selection dialog boolean false
buttonOnly
button-only
If true, shows only a button as a file input boolean false
noFileList
no-file-list
If true, no file list will be shown boolean false
label An optional overwrite for the upload label string | undefined -
buttonLabel
button-label
An optional overwrite for the preview button label string | undefined -
lang The locale to render the component in. string -
accept A string that defines the file types the file dropzone should accept. Defaults to ‘*’ string "*"
maxFileSize
max-file-size
An optional maximum size of a file that will be considered valid. number | undefined -
maxFiles
max-files
The maximum amount of files that are allowed. number -
multiple Indicates if multiple files can be uploaded boolean false
validity Gets the validity state object - -
validationMessage Gets the validation message - -
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
p-drop onPDrop Emitted when dragged files have been dropped on the dropzone area. -
p-change onPChange Emitted when files have been uploaded via the dropzone or file dialog. { fileList: FileList }
p-load onPLoad Emitted when a file transfer was finished { response: unknown }
p-error onPError Emitted when a file transfer threw an error { event: ProgressEvent }
p-abort onPAbort Emitted when a file transfer was aborted by the user { event: ProgressEvent }
p-remove onPRemove Emitted when a file was removed { file: FileInfo }

Learn more about events.

Methods

Name Description Arguments
checkValidity() Checks for validity but does not show a validation message. Returns true when valid and false when invalid. -
getForm() Gets the associated form, if one exists. -
reportValidity() Checks for validity and shows the browser’s validation message if the control is invalid. -
setCustomValidity() Sets a custom validation message. Pass an empty string to restore validity. message: string

Learn more about methods.

Custom Properties

Name Description Default
--border-radius The border radius of the dropzone borders.
--border-width The width of the dropzone borders.
--border-style The style of the dropzone borders.

Learn more about customizing CSS custom properties.

Parts

Name Description
base The component’s internal wrapper.
label The dropzone container.
image The dropzone image.
button The dropzone button.

Learn more about customizing CSS parts.

Dependencies

This component automatically imports the following dependencies.

  • <p-file-upload-item>
  • <p-icon>
  • <p-icon-button>
  • <p-progress-bar>