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

@marccawood/lit-dialogs

v0.1.0

Published

Promise-returning modal dialogs as themeable Lit web components.

Downloads

19

Readme

@marccawood/lit-dialogs

Promise-returning modal dialogs as Lit web components. alert, confirm, prompt and choice, plus the shared chrome to build your own dialogs on.

Depends only on lit. No build tool assumptions, no CSS framework, no icons.

Live example →cd example && npm install && npm run dev

For non-modal notifications see the sibling package @marccawood/lit-toast.

Install

npm install @marccawood/lit-dialogs lit

Use

import { HostDialogs, defineHostDialogs } from '@marccawood/lit-dialogs';

defineHostDialogs();

Render one element in your app shell:

<host-dialogs></host-dialogs>

Then call it from anywhere through the singleton:

await HostDialogs.instance?.alert('Saved.');
const ok = await HostDialogs.instance?.confirm('Delete this table?');
const name = await HostDialogs.instance?.prompt('New name', 'Untitled');
const pick = await HostDialogs.instance?.choice('Export as', ['CSV', 'JSON', 'SQL']);

confirm is choice with Yes/No. Cancel, Escape, and the close-X all resolve nullundefined for alert.

defineHostDialogs(tag) takes an optional tag name and skips an already-registered tag, so importing the module twice is safe.

Why promises

A dialog waits for a person. The native window.confirm blocks the main thread to return its boolean, which a custom element cannot do, so the answer has to arrive later. A promise keeps the call and its consequence on one line:

if (await dialogs.confirm('Delete this table?')) await store.tables.remove(id);

It also makes the queue work. Only one dialog shows at a time, so three calls with no await between them open one after the other instead of fighting over the single <dialog> element.

Build your own dialogs on the same chrome

import { css, html, LitElement } from 'lit';
import { ctrlEnterSubmits, dialogChromeStyles, makeDialogDraggable } from '@marccawood/lit-dialogs';

class MyDialog extends LitElement {
  static styles = [
    dialogChromeStyles,
    css`
      dialog {
        min-width: 420px;
      }
    `,
  ];
  // …
}

The expected markup is a <dialog> with a .close-x button, a <form>, a .dialog-header (title + .header-actions) and a .dialog-body. The full shape is documented at the top of src/dialog-chrome.ts, and example/src/custom-dialog.ts is a working one.

  • ctrlEnterSubmits — wire as @keydown on the <dialog>; Ctrl+Enter and Cmd+Enter submit the form from any field inside.
  • makeDialogDraggable(dialog, header) — a native <dialog> centers itself and cannot be moved; this makes the header a drag handle. Idempotent.

Dialogs go full-screen below 640px viewport width.

Theme

Set these on any ancestor. Every one falls back to the value shown, so a project that sets nothing still looks finished.

| Token | Fallback | | --------------------------------------------------------- | --------------------------------------- | | --dlg-surface | Canvas (the UA <dialog> background) | | --dlg-radius | 0.5rem | | --dlg-font | system-ui, sans-serif | | --dlg-backdrop | rgba(15, 23, 42, 0.4) | | --dlg-header-bg | #1f2937 | | --dlg-header-fg | white | | --dlg-accent / --dlg-accent-hover / --dlg-accent-fg | #3b82f6 / #2563eb / white | | --dlg-border | #d1d5db | | --dlg-text | #374151 |

Shades derived from the dark header bar (its bottom border, the close-X, the ghost button inside it) stay literal. They only make sense against a dark header, so restyle them yourself if you set --dlg-header-bg to a light color.

API

| Export | What it is | | --------------------- | ------------------------------------------------------------------- | | HostDialogs | The element class. HostDialogs.instance is the mounted singleton. | | defineHostDialogs | Guarded customElements.define, default tag host-dialogs. | | dialogChromeStyles | The shared CSSResult for your own dialogs. | | ctrlEnterSubmits | Keydown handler: Ctrl/Cmd+Enter submits the dialog's form. | | makeDialogDraggable | Makes a <dialog> movable by a handle element. |

Develop

npm install
npm run typecheck
npm test
npm run build

Publishing runs from a version tag. Push v0.1.0 and the publish workflow checks the tag against package.json, runs the tests, and publishes to npm.

Origin

Extracted from easyDBAccess, where these dialogs run in a browser app and inside Electron.

License

MIT © Marc Cawood