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

prettier-modals

v0.2.0

Published

Beautiful open/close animations for native <dialog> elements, powered by GSAP Flip.

Readme

Prettier Modals

A tiny JavaScript class that brings beautiful open/close animations to native <dialog> elements using GSAP and its Flip plugin.

The modal morphs from the trigger button and collapses back into it when closed — with elastic easing, blur, and fade effects. No frameworks, no dependencies beyond GSAP.

Features

  • Uses the native HTML <dialog> element (accessible by default)
  • Smooth elastic open animation with blur fade-in
  • Closing animation with border-radius morph, blur, and fade-out
  • Automatic style injection (no extra CSS file needed)
  • Respects prefers-reduced-motion
  • SSR-safe, ships ESM + CJS + TypeScript types
  • Lightweight — GSAP is the only (peer) dependency

Installation

npm install prettier-modals gsap

GSAP is a peer dependency (>=3.12) — install it alongside Prettier Modals. The package ships ESM, CJS, and TypeScript types.

Usage

1. Register the GSAP plugins

Prettier Modals imports GSAP, Flip, and CustomEase internally, but GSAP requires the plugins to be registered once in your app:

import gsap from 'gsap'
import { Flip } from 'gsap/Flip'
import { CustomEase } from 'gsap/CustomEase'

gsap.registerPlugin(Flip, CustomEase)

With a bundler (Vite, webpack, Angular CLI…) this resolves GSAP to a single instance automatically. See Running without a bundler for the CDN setup.

2. Create the instance

import { PrettyModal } from 'prettier-modals'

const prettyModal = new PrettyModal()

3. Add a <dialog> and a trigger

The trigger element is explicit — pass the element the modal should morph from. From an inline handler, use this:

<button onclick="prettyModal.open('my-modal', { trigger: this })">Open</button>

<dialog id="my-modal">
  <h1>Hello world!</h1>
  <button onclick="prettyModal.close('my-modal')">Close</button>
</dialog>

You can pass either an id string or an HTMLElement for both the dialog and the trigger — handy from frameworks where you hold element references:

prettyModal.open(dialogEl, { trigger: buttonEl, anchor: 'origin' })

API

new PrettyModal(options?)

| Option | Type | Default | Description | |---|---|---|---| | anchor | 'center' \| 'origin' | 'center' | Where the modal opens from. origin positions it near the trigger. | | duration | number | 0.5 | Flip animation duration (seconds). | | ease | string | elastic | CustomEase SVG path for the Flip tween. | | respectReducedMotion | boolean | true | Skip animation when the user prefers reduced motion. | | onOpen | (dialog) => void | — | Called after the open animation completes. | | onClose | (dialog) => void | — | Called after the close animation completes. |

These act as defaults; any of them (plus trigger) can be overridden per call via the second argument of open/close.

Methods

| Method | Description | |---|---| | open(dialogRef, options?) | Opens the <dialog> (id or element), morphing from options.trigger. | | close(dialogRef, options?) | Closes the <dialog>, morphing back into its trigger. | | destroy() | Removes the injected <style> tag. Call when tearing down. |

How it works

  1. Open — Pairs the trigger and dialog with a shared data-flip-id, captures the trigger's position with Flip.getState(), calls dialog.showModal(), then uses Flip.from() to morph the dialog out of the trigger with an elastic ease.
  2. Close — Uses Flip.to() to morph the dialog back into its trigger with blur and fade, then calls dialog.close().

CSS keyframe animations handle the blur/fade/border-radius effects during transitions. Styles are auto-injected on instantiation (once per page) so you don't need to import any CSS. The library is SSR-safe — it touches document/window only in the browser.

Demo

The demo lives in demo/ and loads the source directly via an import map (no build step). Because ES modules and import maps require HTTP (not file://), serve it with any static server:

git clone https://github.com/antuuanyf/prettier-modals.git
cd prettier-modals

# any static server works, e.g.:
npx serve .
# or
python3 -m http.server 8000

Then open http://localhost:8000/demo/ (adjust the port) and click the buttons. The demo shows both anchor: 'origin' and anchor: 'center'.

Running without a bundler

In a plain <script type="module"> setup, point an import map at GSAP's combined ESM bundle so gsap, Flip, and CustomEase share one instance (separate per-plugin CDN bundles each ship their own GSAP copy and break Flip):

<script type="importmap">
{
  "imports": {
    "gsap": "https://cdn.jsdelivr.net/npm/[email protected]/all.js/+esm",
    "gsap/Flip": "https://cdn.jsdelivr.net/npm/[email protected]/all.js/+esm",
    "gsap/CustomEase": "https://cdn.jsdelivr.net/npm/[email protected]/all.js/+esm"
  }
}
</script>

Customization

Style your <dialog> however you want with regular CSS. Prettier Modals only handles the animation — layout, colors, and sizing are up to you.

dialog {
  border: none;
  border-radius: 24px;
  width: 100%;
  height: 100%;
  max-width: 400px;
  max-height: 400px;
}

Updating

Check whether a newer version is available and update within your semver range:

npm outdated prettier-modals          # is there a newer version?
npm update prettier-modals            # update within your "^" range (patches + minors)
npm install prettier-modals@latest    # jump to the latest, including a new major

GSAP is a peer dependency, so keep it current too (npm update gsap).

Using the Angular wrapper? It ships as a separate package. Update both — the wrapper does not pull a new core for you:

npm update prettier-modals-angular prettier-modals

Get notified of new versions: every release is published as a GitHub Release. Click Watch → Custom → Releases on the repo to be notified whenever a new version ships, and see each release's notes for what changed.

Browser Support

Works in all modern browsers that support <dialog> and ES modules (Chrome, Firefox, Safari, Edge).

License

MIT License

Copyright (c) 2026 srdavo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

Credits

Maintained by Antonio Monreal Diaz, based on the original work by srdavo. Powered by GSAP.