{"id":13494666,"url":"https://github.com/simonwep/nanopop","last_synced_at":"2025-05-13T23:04:20.752Z","repository":{"id":49603678,"uuid":"262355364","full_name":"simonwep/nanopop","owner":"simonwep","description":"🍦 Minimalistic, small, positioning engine. Build for high-performance, minimal footprint and maximum control over positioning behavior.","archived":false,"fork":false,"pushed_at":"2025-03-09T15:47:33.000Z","size":482,"stargazers_count":716,"open_issues_count":3,"forks_count":13,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-30T04:13:56.705Z","etag":null,"topics":["popper","positioning-engine","widget"],"latest_commit_sha":null,"homepage":"https://simonwep.github.io/nanopop","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simonwep.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-08T15:10:28.000Z","updated_at":"2025-03-26T09:32:38.000Z","dependencies_parsed_at":"2024-01-13T17:12:02.555Z","dependency_job_id":"ccc6100d-191d-439d-a2b2-2e0fb9b015cf","html_url":"https://github.com/simonwep/nanopop","commit_stats":{"total_commits":79,"total_committers":7,"mean_commits":"11.285714285714286","dds":"0.12658227848101267","last_synced_commit":"5a5335b1bdb2f3dcbb0533c75adec781250dc606"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonwep%2Fnanopop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonwep%2Fnanopop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonwep%2Fnanopop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonwep%2Fnanopop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simonwep","download_url":"https://codeload.github.com/simonwep/nanopop/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254040488,"owners_count":22004551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["popper","positioning-engine","widget"],"created_at":"2024-07-31T19:01:27.025Z","updated_at":"2025-05-13T23:04:20.688Z","avatar_url":"https://github.com/simonwep.png","language":"TypeScript","funding_links":["https://github.com/sponsors/Simonwep"],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003ch3 align=\"center\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/30767528/81419142-155b4100-914e-11ea-913b-cb9f0cccd4e2.png\" width=\"500\" alt=\"Logo\"\u003e\n\u003c/h3\u003e\n\n\u003ch3 align=\"center\"\u003e\n    Ultra Tiny, Opinionated Positioning Engine\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"gzip size\" src=\"https://img.badgesize.io/https://cdn.jsdelivr.net/npm/nanopop/dist/nanopop.mjs?compression=gzip\u0026style=flat-square\"\u003e\n  \u003cimg alt=\"brotli size\" src=\"https://img.badgesize.io/https://cdn.jsdelivr.net/npm/nanopop/dist/nanopop.mjs?compression=brotli\u0026style=flat-square\"\u003e\n  \u003ca href=\"https://github.com/Simonwep/nanopop/actions\"\u003e\u003cimg\n     alt=\"Build Status\"\n     src=\"https://img.shields.io/github/workflow/status/Simonwep/nanopop/CI?style=flat-square\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/nanopop\"\u003e\u003cimg\n     alt=\"Download count\"\n     src=\"https://img.shields.io/npm/dm/nanopop.svg?style=popout-square\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"No dependencies\" src=\"https://img.shields.io/badge/dependencies-none-27ae60.svg?style=popout-square\"\u003e\n  \u003ca href=\"https://www.jsdelivr.com/package/npm/nanopop\"\u003e\u003cimg\n     alt=\"JSDelivr download count\"\n     src=\"https://data.jsdelivr.com/v1/package/npm/nanopop/badge\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Current version\"\n       src=\"https://img.shields.io/github/tag/Simonwep/nanopop.svg?color=3498DB\u0026label=version\u0026style=flat-square\"\u003e\n  \u003ca href=\"https://github.com/sponsors/Simonwep\"\u003e\u003cimg\n     alt=\"Support me\"\n     src=\"https://img.shields.io/badge/github-support-3498DB.svg?style=popout-square\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\nNanopop is an ultra-tiny positioning engine. Hold up, isn't there [PopperJS](https://github.com/popperjs/popper-core)?\nYeah - 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.\n\n#### When should I use Nanopop and not PopperJS?\n1. Situations where you want **full control** over positioning, including handling events such as scrolling, and manual resizing.\n2. **Performance-critical** cases with lots of elements [...] nanopop will only makes changes if you say so.\n3. Poppers with **minimal footprint** such as drop-downs and tooltips which don't require that much configurability.\n4. 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!\n\nThis library was originally part of [pickr](https://github.com/Simonwep/pickr) - now ported to TS with tests and a few updates / bug-fixes.\n\n\u003e Heads up! This is the readme for v2 - if you're looking for the first version head over [here](https://github.com/Simonwep/nanopop/tree/539de9558a113ca6548a0d7d316ae8c65d7817d5) (v1 is not maintained anymore).\n\n## Getting Started\n\nInstall via npm:\n```shell\n$ npm install nanopop\n```\n\nInstall via yarn:\n```shell\n$ yarn add nanopop\n```\n\nInclude directly via jsdelivr:\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/nanopop/dist/nanopop.umd.js\"\u003e\u003c/script\u003e\n```\n\nUsing [JavaScript Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules):\n\n````js\nimport {\n    reposition,   // Core, stateless function to reposition an element\n    createPopper, // Stateful function which keeps track of your configuration\n    defaults,     // A subset of nanopops options used as default values\n    version       // Current version\n} from 'https://cdn.jsdelivr.net/npm/nanopop/lib/nanopop.min.mjs'\n````\n\n\u003e 🌟 Index is fully tree-shakable! E.g. if you only use `reposition` you'll probably end up with less than 500B code!\n\n## Usage\n\n```js\nreposition(\n    /* reference: */ document.querySelector('.btn'),\n    /* popper: */ document.querySelector('.dropdown'),\n    /* We're using the default options */\n);\n```\n\n\u003e ⚠ The popper-element must have set `position` to `fixed`.\n\n\u003e ℹ 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;}`)\n\n#### All options\n```ts\nimport {reposition, createPopper} from 'nanopop';\n\n// Using a object and reposition directly\nconst nanopop = reposition(reference, popper, {\n\n    // The DOMRect of the container, it used the html-element as default.\n    // You could also create your own boundary using a custon DOMRect (https://developer.mozilla.org/en-US/docs/Web/API/DOMRect)!\n    container: document.documentElement.getBoundingClientRect(),\n\n    // Optional arrow element that is positioned between the popper and the reference element.\n    arrow: undefined,\n\n    // Margin between the popper element and the reference\n    margin: 8,\n\n    // Minimum space between the popper and the container\n    padding: 0,\n\n    // Preferred position, any combination of [top|right|bottom|left]-[start|middle|end] is valid.\n    // 'middle' is used as default-variant if you leave it out.\n    position: 'bottom-middle',\n\n    // In case the variant-part (start, middle or end) cannot be applied you can specify what (and if)\n    // should be tried next.\n    variantFlipOrder: {\n        start: 'sme', // In case of -start try 'start' first, if that fails 'middle' and 'end' if both doesn't work.\n        middle: 'mse',\n        end: 'ems'\n    },\n\n    // The same as variantFlipOrder, but if all variants fail you might want to try other positions.\n    positionFlipOrder: {\n        top: 'tbrl', // Try 'top' first, 'bottom' second, 'right' third and 'left' as latest position.\n        right: 'rltb',\n        bottom: 'btrl',\n        left: 'lrbt'\n    }\n});\n\n/**\n * Using the createPopper function to create a stateful wrapper\n *\n * Correct ways of calling it are:\n * createPopper(reference: HTMLElement, popper: HTMLElement, options?: NanoPopOptions)\n * createPopper(options?: NanoPopOptions)\n * ⚠ If you omit options entierly you'll have to set both the reference and the popper later when calling .update!\n */\nconst popper = createPopper({...});\npopper.update(); // You can pass an object to update which will get merged with the existing config.\n```\n\nCalling `popper.update(...)` or `reposition(...)` both returns a position-pair (For example `te` for **T**op-**E**nd) or `null` based on if it was possible to find a position for the popper without clipping it._\n\n\u003e Tip: The returned position-pair is perfect for tool-tips to give them a little arrow!\n\n## Caveats\n1. The popper-element must have `position` set to `fixed`.\n2. 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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonwep%2Fnanopop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonwep%2Fnanopop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonwep%2Fnanopop/lists"}