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 🙏

© 2024 – Pkg Stats / Ryan Hefner

nanopop

v2.4.2

Published

Ultra tiny, opinionated, positioning engine.

Downloads

464,458

Readme

Nanopop is an ultra-tiny positioning engine. Hold up, isn't there PopperJS? Yeah - and PopperJS is great! But there are tons of features that, in most cases, you just might not need. This library is less than a third of PopperJS.

When should I use Nanopop and not PopperJS?

  1. Situations where you want full control over positioning, including handling events such as scrolling, and manual resizing.
  2. Performance-critical cases with lots of elements [...] nanopop will only makes changes if you say so.
  3. Poppers with minimal footprint such as drop-downs and tooltips which don't require that much configurability.
  4. You might have some special needs about how your popper behaves. Index exposes a function for the sole purpose of positioning something, use it in your own library!

This library was originally part of pickr - now ported to TS with tests and a few updates / bug-fixes.

Heads up! This is the readme for v2 - if you're looking for the first version head over here (v1 is not maintained anymore).

Getting Started

Install via npm:

$ npm install nanopop

Install via yarn:

$ yarn add nanopop

Include directly via jsdelivr:

<script src="https://cdn.jsdelivr.net/npm/nanopop/dist/nanopop.umd.js"></script>

Using JavaScript Modules:

import {
    reposition,   // Core, stateless function to reposition an element
    createPopper, // Stateful function which keeps track of your configuration
    defaults,     // A subset of nanopops options used as default values
    version       // Current version
} from 'https://cdn.jsdelivr.net/npm/nanopop/lib/nanopop.min.mjs'

🌟 Index is fully tree-shakable! E.g. if you only use reposition you'll probably end up with less than 500B code!

Usage

reposition(
    /* reference: */ document.querySelector('.btn'),
    /* popper: */ document.querySelector('.dropdown'),
    /* We're using the default options */
);

⚠ The popper-element must have set position to fixed.

ℹ Because the default-container is document.documentElement you might have to increase the height of the html element to make room for your popper (e.g. html {height: 100vh;})

All options

import {reposition, createPopper} from 'nanopop';

// Using a object and reposition directly
const nanopop = reposition(reference, popper, {

    // The DOMRect of the container, it used the html-element as default.
    // You could also create your own boundary using a custon DOMRect (https://developer.mozilla.org/en-US/docs/Web/API/DOMRect)!
    container: document.documentElement.getBoundingClientRect(),

    // Optional arrow element that is positioned between the popper and the reference element.
    arrow: undefined,

    // Margin between the popper element and the reference
    margin: 8,

    // Minimum space between the popper and the container
    padding: 0,

    // Preferred position, any combination of [top|right|bottom|left]-[start|middle|end] is valid.
    // 'middle' is used as default-variant if you leave it out.
    position: 'bottom-middle',

    // In case the variant-part (start, middle or end) cannot be applied you can specify what (and if)
    // should be tried next.
    variantFlipOrder: {
        start: 'sme', // In case of -start try 'start' first, if that fails 'middle' and 'end' if both doesn't work.
        middle: 'mse',
        end: 'ems'
    },

    // The same as variantFlipOrder, but if all variants fail you might want to try other positions.
    positionFlipOrder: {
        top: 'tbrl', // Try 'top' first, 'bottom' second, 'right' third and 'left' as latest position.
        right: 'rltb',
        bottom: 'btrl',
        left: 'lrbt'
    }
});

/**
 * Using the createPopper function to create a stateful wrapper
 *
 * Correct ways of calling it are:
 * createPopper(reference: HTMLElement, popper: HTMLElement, options?: NanoPopOptions)
 * createPopper(options?: NanoPopOptions)
 * ⚠ If you omit options entierly you'll have to set both the reference and the popper later when calling .update!
 */
const popper = createPopper({...});
popper.update(); // You can pass an object to update which will get merged with the existing config.

Calling popper.update(...) or reposition(...) both returns a position-pair (For example te for Top-End) or null based on if it was possible to find a position for the popper without clipping it._

Tip: The returned position-pair is perfect for tool-tips to give them a little arrow!

Caveats

  1. The popper-element must have position set to fixed.
  2. If nanopop cannot find a position without clipping your popper it'll revert its top and left values - you can use css / js to handle this case.