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

@bayonai/ui

v0.3.0

Published

Accessible React and Material UI primitives extracted from Bayon applications.

Readme

@bayonai/ui

React 19 / Material UI 9 primitives for Bayon applications. Thunderlist is the first consumer. The package ships tree-shakeable ESM and CommonJS artifacts, TypeScript declarations, and explicit client-entry directives for all public subpaths. It is versioned independently from the host application.

Consumers must provide the peer dependencies declared in package.json: React and React DOM 19.2, Material UI 9, Material UI icons, and Emotion 11. React framework consumers can import the documented subpaths directly; no root export is intentionally provided. The package supports Node 20+ for build and release tooling and browsers supported by the installed React/MUI peer versions.

Actions

Import LoadingIconButton, ActionMenu, and StickyActionFooter from @bayonai/ui/actions.

  • LoadingIconButton preserves a MUI icon button's footprint while replacing its child with a labelled spinner and disabling repeat interaction. Consumers provide both the ordinary aria-label and the in-flight loadingLabel; tooltips and request ownership remain with the host component.
  • ActionMenu owns the accessible overflow trigger, optional loading state, section grouping, disabled actions, and neutral MUI semantic colors. Use actionColorSx for an explicit host-theme override. The host owns the action list, callbacks, authorization, navigation, and request lifecycle.
  • StickyActionFooter provides semantic, locally sticky footer chrome for the final actions of a long form. It stays at the bottom of the host's scroll container while the form scrolls. The host supplies its actions, decides whether they are full width, and uses sx for any edge-to-edge bleed inside a padded surface.

Dialog layout, action placement, confirmation policy, and close behavior stay in host applications until multiple consumers share the same product contract. Likewise, user avatars and account menus stay downstream: hosts own identity loading, image fallbacks, authentication, sign-out effects, navigation, copy, menu contents, and touch/layout policy.

Feedback

Import StatusNotice from @bayonai/ui/feedback. It renders neutral information, success, warning, and error presentation for strings or rich React content. Consumers may supply host-owned action content, root sx, a dataComponent marker, and an explicit role such as alert. Error notices retain role="status" by default for compatibility. Stable data-status-notice-part markers identify the icon, message, and optional action so branded adapters do not depend on generated Material UI classes.

The package only renders action content. It deliberately does not invoke, disable, retry, sanitize, translate, log, or infer the meaning of messages or actions; host adapters retain request state, accessibility urgency, and user-facing error policy.

Uploads

Import FileUpload, FileRow, FileThumbnail, FileViewer, UploadProgressRing, and useUploadLock from @bayonai/ui/uploads.

  • UploadFile supplies neutral file identity, name, MIME type, byte size and source URL. Generic components preserve extra host fields without depending on them.
  • FileUpload owns picker interactions, a synchronous upload lock, busy/error UI, selection and separators. Supply controlled attachments and onUploadAttachment. The host updates the list when persistence completes. renderFile and renderViewer compose the other components. RowShell, FieldIcon, and colors let the host preserve its detail layout without app imports inside the package.
  • FileRow makes thumbnail/name/size one preview target and composes SwipeActionRow. thumbnail and sizeLabel are slots; delete and preview callbacks receive the original file.
  • FileThumbnail receives a stable loadFile(file, signal) callback. It manages private raster thumbnails, loading/error fallback and owned object URL cleanup. Host-owned local blob URLs are not revoked.
  • FileViewer receives loadFile and onDownload. File previews use raster/media decoders, sandboxed browser PDF support or escaped text; other formats offer download. PDF rendering depends on the browser/WebView. Loading, media-decoding and download failures are logged and displayed. File-specific state resets internally when the selected file changes.
  • useUploadLock prevents repeated upload events before a React rerender. Existing non-task uploaders also reuse this hook through the host adapter.
  • UploadProgressRing wraps a compact upload target with an accessible, determinate circular progress indicator. Supply the host-owned target as children, a progress percentage (or null while idle), and a specific progressLabel. It clamps the visual value to 0–100 and disables pointer events on the ring, so the host controls picker interaction and its disabled state. Use it when progress should stay attached to the object being changed, such as an avatar; keep error and recovery controls in the host near the target.

The host retains Firebase authentication, access checks, MIME/size validation, task mutations, offline queue ownership, filename-preserving downloads and user-facing error mapping. accept is a picker hint, not validation. UploadProgressRing deliberately does not start uploads, infer an error state, replace its target, or manage retries; that lifecycle belongs to the host.

No tooltips are added. Field rows retain their full-width separators; the populated uploader/file-list join retains the requested 80% divider.

Swipe

Import SwipeActionRow from @bayonai/ui/swipe.

Wrap row content and supply onDelete and canDelete. A left pull past 72px invokes the callback; the host decides whether this opens confirmation, starts undo, or deletes immediately. Keep an accessible button for keyboard/mouse deletion. The row does not own persistence or confirmation.

Vertical scrolling, right pulls, short gestures and cancellation do not invoke deletion. Permission is checked again on release. The immediate trailing click is consumed so a swipe cannot also open the preview. Horizontal movement uses a 12px direction threshold and a 104px maximum visual offset. Motion settles respect reduced-motion preferences.

This first extraction migrates attachment swipes. Task/subtask rows also have right-pull copy and drag ownership; migrate them after extending the shared action contract and preserving those behaviors.

Toasts

Import Toast, ActionToast, and useUpwardToastDismiss from @bayonai/ui/toasts. Toast supplies a generic themed surface, placement, live-region role and optional upward gesture dismissal. ActionToast adds message, actionLabel, actionAriaLabel, onAction, and optional actionDisabled; it can use a host-styled ToastComponent.

There are no automatic timers or transaction rules in the package. The host controls lifetime, undo eligibility, operation identity, and what dismissal means. Action button taps are excluded from drag initiation. A 64px upward pull dismisses; short pulls return to their origin. No action tooltips are added. Mobile top/bottom offsets are configurable; Thunderlist's AppToast adapter keeps its navigation offsets and branded surface.

Task deletion and move notifications now use ActionToast, with their original copy, undo callbacks and expiry timers retained in the app. Other AppToast consumers use the extracted shell via the existing adapter.

Drawers

Import MobileBottomDrawer, MobileBottomDrawerHeader, BottomDrawer, ResponsiveDrawer, useVisualViewportBottomInset, and getVisualViewportBottomInset from @bayonai/ui/drawers.

These components are now consumed by Thunderlist's existing drawer adapters. appearance supplies background, chrome, handle color, shadow and safe-area padding with neutral MUI defaults. Close tooltips are optional; accessible close labels remain present.

MobileBottomDrawer mounts open; a user close or dismiss signal animates before calling onClose (220ms, immediate callback with reduced motion). The host unmounts after that callback. Timers are cancelled on unmount; withdrawing a pending external dismiss cancels it. MUI continues to own focus restoration, nested-modal focus and scroll-aware touch dismissal. contentScrollMode selects container or child scroll ownership. Header actions and handle placement preserve the existing layouts.

BottomDrawer is a controlled bottom-anchored drawer, also used for desktop presentation in Thunderlist. Portal ownership is configurable and defaults to MUI's portal behavior; Thunderlist's adapters disable the portal for their route slots. ResponsiveDrawer chooses mobile below 900px and desktop otherwise; it forwards separate callbacks and a presentation argument to its content. It does not navigate or broadcast exclusive-modal events. Route/back-button behavior stays with the host.

The viewport hook reports the area obscured below the visual viewport and cleans up resize/scroll subscriptions. Host screens choose where to apply it; extraction does not automatically reposition every drawer for the keyboard.

Behavior acceptance checklist

Drawer extraction must include behavior, not just appearance:

  • Bottom pull-to-dismiss with existing timing, velocity behavior and reduced motion.
  • Scroll ownership: container versus child, nested content, vertical scroll at the top boundary.
  • Horizontal action gestures must not trigger vertical sheet dismissal.
  • Header/handle placement, safe areas, visual viewport and on-screen keyboard.
  • Focus entry/restoration, Escape/backdrop dismissal and nested dialogs that preserve the parent sheet.
  • Desktop bottom drawer versus mobile sheet; route/back-button and portal policy remain in host adapters.

The existing Thunderlist lifecycle, markup, responsive and viewport tests now exercise these package components through their adapters. Package tests also cover cancelled external dismissal and unmount during a user-close animation. Real native touch verification is still a separate release check. The legacy data-drawer-gesture-exclude marker alone is not proof of arbitration; the current sheet uses MUI's gesture implementation.

September 9 browser smoke check: a disposable harness using the actual source with React/MUI verified 1440px desktop and 390×844 mobile presentation, open/close, focus return to the opener, nested Dialog closure preserving its parent drawer, and constrained container scrolling without console errors. Child mode's hidden outer overflow was checked, but a scrolling child was not exercised. Physical touch gestures and native keyboard behavior remain release checks.

Validation

Run corepack pnpm --filter @bayonai/ui run release:check from the workspace root before every release. It type-checks and tests the source, builds ESM, CommonJS, and declaration artifacts, creates the npm tarball, installs that tarball into an isolated consumer, and verifies each export with ESM, CommonJS, and TypeScript resolution. CI runs the same gate.

After that command is green, follow the package release runbook at docs/UI_PACKAGE_RELEASE.md. Host attachment tests continue to exercise the package via thin adapters. Browser/emulator rendering and gesture verification remains a release check for the actual application targets; record that evidence in the release pull request before publishing a supported public release.

Use a consumer application to exercise uploads, file previews, swipe deletion, responsive drawers, toasts, error/disabled states, and themes. Thunderlist's development-only /ui-playground route remains a consumer integration harness; it is not part of this package or Bounded's product surface.