Ultra Tiny, Opinionated Positioning Engine
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?
- Situations where you want full control over positioning, including handling events such as scrolling, and manual resizing.
- Performance-critical cases with lots of elements [...] nanopop will only makes changes if you say so.
- Poppers with minimal footprint such as drop-downs and tooltips which don't require that much configurability.
- 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,
createPopper,
defaults,
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(
document.querySelector('.btn'),
document.querySelector('.dropdown'),
);
⚠ 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';
const nanopop = reposition(reference, popper, {
container: document.documentElement.getBoundingClientRect(),
arrow: undefined,
margin: 8,
padding: 0,
position: 'bottom-middle',
variantFlipOrder: {
start: 'sme',
middle: 'mse',
end: 'ems'
},
positionFlipOrder: {
top: 'tbrl',
right: 'rltb',
bottom: 'btrl',
left: 'lrbt'
}
});
const popper = createPopper({...});
popper.update();
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
- The popper-element must have
position
set to fixed
. - 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.