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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@globus.studio/oat-upload

v0.1.1

Published

Dropzone, previews, validation, removal, and progress for native file inputs in Oat UI

Readme

Oat Upload

Dropzone, file previews, validation, removal, and progress for native <input type="file"> in Oat UI.

Oat Upload is a small, zero-runtime-dependency extension for Oat. It keeps the native file input as the source of truth and adds progressive behavior around it:

  • drag and drop over a semantic file input
  • image and file previews
  • remove selected files before submit
  • size, type, and count validation
  • progress via native <progress>
  • form-friendly file syncing where the browser supports DataTransfer
  • events for app code: ot-upload-change and ot-upload-error

Without JavaScript, users still get a regular <input type="file">. With JavaScript, <ot-upload> builds the richer upload surface.

Oat Upload file upload demo

Install

With npm:

npm install @globus.studio/oat-upload
import '@globus.studio/oat-upload/css';
import '@globus.studio/oat-upload';

From a CDN:

<link rel="stylesheet" href="https://oat.ink/oat.min.css">
<link rel="stylesheet" href="https://unpkg.com/@globus.studio/[email protected]/dist/oat-upload.min.css">
<script src="https://oat.ink/oat.min.js" defer></script>
<script src="https://unpkg.com/@globus.studio/[email protected]/dist/oat-upload.min.js" defer></script>

Basic Usage

<ot-upload max-size="5242880" max-files="5">
  <input type="file" name="attachments" multiple accept="image/*,.pdf">
</ot-upload>

That is enough. Oat Upload creates the dropzone, preview list, status output, and progress element.

Custom Markup

Use data-upload-* parts when you want to control the HTML.

<ot-upload max-size="5242880" max-files="3">
  <input id="files" type="file" name="files" multiple accept="image/*,.pdf">

  <label data-upload-dropzone for="files">
    <strong>Drop files here</strong>
    <small class="text-light">Images or PDF, up to 5 MB each.</small>
  </label>

  <output data-upload-error role="status" aria-live="polite"></output>
  <ul data-upload-list aria-label="Selected files"></ul>
  <progress data-upload-progress max="100" value="0" hidden></progress>
  <output data-upload-status aria-live="polite"></output>
</ot-upload>

Validation

Validation reads from the native input first, then from <ot-upload> attributes.

<ot-upload accept="image/*,.pdf" max-size="5242880" max-files="5">
  <input type="file" multiple>
</ot-upload>

| Attribute | Element | Description | | --------- | ------- | ----------- | | accept | input, ot-upload | Comma-separated extensions or MIME types. Supports image/*. | | max-size | ot-upload | Max bytes per file. | | max-files | ot-upload | Max accepted files. | | multiple | input | Allows more than one file. Without it, new selection replaces the previous file. | | disabled | input, ot-upload | Disables drop and picker behavior. |

Rejected files trigger ot-upload-error and are not added to the selected list.

Progress

Use the native progress element generated by the component or provide your own with data-upload-progress.

const upload = document.querySelector('ot-upload');

upload.setProgress(0);
upload.setProgress(65);
upload.setProgress(100);

Passing null or calling resetProgress() hides the progress element.

upload.resetProgress();

Events

const upload = document.querySelector('ot-upload');

upload.addEventListener('ot-upload-change', (event) => {
  console.log(event.detail.files);
  console.log(event.detail.added);
  console.log(event.detail.removed);
});

upload.addEventListener('ot-upload-error', (event) => {
  console.log(event.detail.reason);
  console.log(event.detail.message);
});

ot-upload-change detail:

| Property | Description | | -------- | ----------- | | files | Current accepted files. | | added | Files added by the current operation. | | removed | Files removed by the current operation. | | rejected | Rejected files from the current operation. |

ot-upload-error detail:

| Property | Description | | -------- | ----------- | | file | Rejected file, when available. | | reason | type, size, count, or disabled. | | message | Human-readable message. |

API

const upload = document.querySelector('ot-upload');

upload.files;              // accepted files
upload.addFiles(files);    // FileList or File[]
upload.remove(fileOrId);   // File, item id, or index
upload.clear();            // remove all files
upload.setProgress(42);    // update native progress
upload.resetProgress();    // hide progress

Development

npm install
npm run check

npm run check builds dist/ and runs the DOM test suite.

Publishing

npm run check
npm publish --dry-run
npm publish

The package is configured for public scoped npm publishing with publishConfig.access.

License

MIT.