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

@techaaroorian-ui/file-intake

v0.2.0-alpha.2

Published

Atomic file batch validation with structured errors and an optional React adapter.

Readme

File Intake

Install the alpha package:

npm install @techaaroorian-ui/file-intake@alpha

Atomic file batch validation extracted from Yuwbrndr's asset uploads. Framework-independent core and optional React hook. No CSS, upload service, object URLs, or storage policy.

Compact drop-zone interaction

import { useFileDropzone } from '@techaaroorian-ui/file-intake/react';
const { dropzoneProps, inputProps, open, errors, isDragging } = useFileDropzone({
  maxFiles: 5,
  maxFileBytes: 2 * 1024 * 1024,
  accept: ['image/png', 'image/jpeg', 'image/webp'],
  existingCount: assets.length,
  disabled: assets.length >= 5,
  onAccepted: files => addAssets(files),
});
<div {...dropzoneProps} className="aar-dropzone" role="group" aria-label="Image intake">
  <span>Drop images here</span>
  <button onClick={open}>Choose images</button>
  <input {...inputProps} className="aar-visually-hidden" tabIndex={-1} aria-label="Image files" />
</div>

The hook supplies file-only drop handling, nested drag tracking, a chooser trigger, same-file reselection, and the latest validation result. Render errors in an announced, persistent region; label the file input and provide a native button as the keyboard/touch alternative. Browser selection and drops use the same atomic validation and existingCount. onAccepted runs only for valid, nonempty batches. clear() clears validation feedback, not the application's asset list.

For other frameworks, bindFileDropzone(element, options) supplies the browser behavior. Pass onResult, optional onDragChange, and getter callbacks for existingCount and disabled; call destroy() on unmount. It ignores non-file drags, prevents dropped files navigating the page within the bound target, and skips disabled intake. Provide a separate native input wired to validateFiles. The core validator remains usable without browser globals.

Aar Loom provides compact aar-file-intake, aar-dropzone, aar-file-list, aar-file-row, aar-file-details, and aar-file-preview anatomy. The docs demonstrate retained assets, per-file removal, count limits, and local raster previews. These are consumer-owned composition and resource handling: the package does not allocate preview URLs or store assets. Preview URLs must be revoked on removal/unmount. Do not nest action buttons inside a clickable drop-zone button.

import { validateFiles } from '@techaaroorian-ui/file-intake';
const result = validateFiles(input.files, {
  maxFiles: 5,
  maxFileBytes: 2 * 1024 * 1024,
  accept: ['image/*', '.png'],
}, existingAssets.length);
if (result.errors.length === 0) {
  // Create object URLs or upload accepted files only after full validation.
}
import { useFileIntake } from '@techaaroorian-ui/file-intake/react';
const intake = useFileIntake({ maxFiles: 5, maxFileBytes: 2 * 1024 * 1024 });
// intake.validate(event.currentTarget.files ?? [], existingAssets.length)
// intake.errors: render persistent, labeled error feedback.
// intake.clear(): clear the latest validation result.

Pass an iterable of files or metadata objects with name, size, and type. FileList works directly. Limits default to unlimited. maxFiles includes existing items. Byte limits are inclusive. Accept patterns support exact MIME types, MIME families (image/*), and case-insensitive extensions (.png). Any error rejects the whole batch. Empty input produces an empty successful result. Errors have count, size, type, or metadata codes for caller-owned messages. Malformed limits throw.

MIME/extension checks use supplied metadata, not file contents. Validate again at any upload service. Create and revoke object URLs in the consuming application; this package allocates none. The hook retains references to the last batch until the next validation or clear. It does not keep a running asset collection.

Consumers provide a labeled file input, optional drop handling, progress, and storage. Always offer file selection as an alternative to dragging. React 18+ is required only for /react; the core works without React or browser globals.

Alpha: APIs may change. ESM and TypeScript declarations; no CommonJS build.

AI agent integration

See the included AI.md for public import paths and integration guidance. Complete package examples remain in this README.