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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@qnc/drag_sorter

v0.4.1

Published

Work-in-progress

Readme

DEPRECATED. Use @qnc/drag_sorter2, instead

drag_sorter2 is intended to replace drag_sorter, but you can have both installed. drag_sorter chose an unfortunate "swapping approach" when moving a child around in a 2-D layout. drag_sorter2 uses the conventional approach (sibling elements retain respective order). The change in approach also necessitated a change in the callback signatures.

Important points

  • you can only reorder children of a single element
  • works on all current AND future children of the parent (ie. you can add children after making the parent sortable, and those children will also be draggable)
  • works with horizontal, vertical, or 2-D layouts
  • original element is set to "visibility: hidden" while being dragged (to leave a space)
  • we clone the element, and that's what you drag around
  • the clone is appended to the parent, with z-index 1; it's up to you to ensure this stacks properly on your page
  • you probably want to set "cursor: grab" on your draggable elements; we set "cursor: grabbing" WHILE dragging

Swapping/sorting algorithm (NOT GOOD)

When dragging an element in some type of grid layout, there are multiple algorithms one could use. SortableJS, for example, will relocate ONLY the dragged element; the other siblings will always maintain their respective order. This equivalent to saying that the dragged element may only ever "swap" with its previous or next sibling (consective swaps may move the dragged element multiple positions, but all other siblings maintain their ordering).

We take another approach. The dragged element may "swap", in a single move, with any of it's sibling elements.

These two algorithms produce notably different effects when dragging an element in a sortable grid layout.

Our "swapping" algorithm is considered part of our contract. We will never switch to the SortableJS approach. We may, however, add an option so that you can opt-in to the SortableJS approach.

Aargh! I regret choosing this as the default algorithm. It can "push" siblings around in unexpected ways. It can be neat for a "let's play and move things around" type for interface, but it's not good for a SORTING interface (where you want to be able to pick up X and move it within the list without messing up the order of other items).

TODO/Ideas

  • animate into final position on release (shouldn't bee too bad)
  • animate sibling swaps (fairly difficult)
  • touch screen support (might already be done???)

Unstable swaps / thrashing

When dragging a small element over a larger element, you can end up with an unstable position where the two siblings keep swapping back and forth. Need to fix this! It would probably be sufficient to say that the dot_product(movement_vector, sibling_vector) must be greater than HSL, rather than HSL/2. This makes swaps happen "later". This might lead to situations where it's difficult to move an element to the beginning or end of the list. I think the ideal algorithm is: - compute drag-child's center - compute drag-child's "projected center" (if we were to swap) - let midpoint = midpoint(current center, projected center) - swap with sibling IFF we've moved "past" the midpoint (reduces to the same as the current algorithm when siblings have equal size)

Computing "projected center" is likely impossible, however, without actually swapping and resetting

Usage

  • npm install --save-dev @qnc/drag_sorter
  • import {enable, disable} from "@qnc/drag_sorter
  • use something like esbuild to build your app

Reminder: we've included drag_sorter.d.ts (typescript definition file), so you can import from typescript with full support, but the module is pre-built, so you don't need to use typescript compiler when building/bundling.