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

@csedl/stimulus-dropdown

v2.2.2

Published

Dropdown and Tooltip with stimulus and floating-ui

Downloads

103

Readme

Stimulus Dropdown

Dropdown with stimulus, based on floating-UI.

Links:

Import and config

import {StimulusDropdown} from "@csedl/stimulus-dropdown"
StimulusDropdown.debug = false

All configurations and their defaults are as follows:

debug: false
closeButtonSelector: '.close-button'
dropdownContentSelector: '.content'
  // when a data-src attribute is added to the panel, the content-tag is replaced by the result of the xhr-response
tooltipContentSelector: '.content'
  // same as dropdownContentSelector
addArrow: true
  // add element with id #arrow within the panel, on opening
persistTooltipOnClick: false
  // clicking on the tooltip-label causes the tooltip-panel to persist open
  // this may mostly be helpful for development, so you may make it environment-dependent

Example

There is a online example app

<div data-controller="csedl-dropdown" data-panel-id="dropdown-panel-3h5k7l4">
    Button
</div>
<div id="dropdown-panel-3h5k7l4" class="hide dropdown-panel-example-class">
    ... any content
</div>

What it does

  • When the button is clicked, it toggles the hide class on the panel and places the panel using floating-ui.
  • When the panel is open, the has-open-panel class is added to the button, otherwise it is removed.
  • Adds functionality to close all panels when clicking outside a panel.
  • When a data-src attribute is given to the panel, on opening the panel, it fires a xhr request and replaces the configured content-tags (see: content-selectors on configs) by the response.
  • This all works with stacked panels too (panel in panel).

Close on click outside

When a dropdown is open, it closes when clicking outside a panel.

This behaviour can be stopped on:

  • The clicked element or its parent elements has the data-dropdown-persist (not: data-dropdown-persist="false") attribute.
  • the event has the attribute event.detail.dataDropdownPersist set to true.

Flexibility

The functions of this package are intended to give flexibility on various ways building a dropdown.

Important: When creating or initializing the dropdown, always call the initialize function before attaching a listener to the panel's close event. The initialize function adds a close event listener to the panel that executes the onPanelClose function. If your custom close function destroys the panel, this has to be done after the onPanelClose is fired by the close event.

Requirements

  • The class dropdown-panel-example-class must be set to position: absolute;.
  • The class hide must be set to display: none;.

Options

  • If there is an element with ID arrow inside the dropdown panel, it is treated as described on floating-ui.
  • The data-placement attribute on the panel can be used to control positioning, see floating-ui/placements.

Events

Events on the button element:

  • place-panel places the panel, and, if present, the arrow element, by floating-ui.

Events the panel element:

  • close closes the panel.
  • place-me like place-panel on the button.

Event Triggers on the button element:

  • before-open-panel
  • after-close-panel

Event Triggers on the panel element:

  • before-open

Helpers

If the panels are rendered to a different location than the button (see z-index on rails-app), within a scrollable (e.g.) container, the button would scroll away from the panel. For such cases, add this both data-attributes to the scrollable element:

<div data-controller="csedl-place-dropdown-panels" data-on="scroll" data-run-after="500" style="overflow: scroll;">
    ...
</div>

Now, on scrolling, it searches for all dropdown-buttons (by class-name has-open-panel) and triggers the place-panel event there.

Options

data-on Attribute:

  • scroll triggered by scroll Event of the given element.
  • resize-observer triggered by ResizeObserver on the given element.

data-run-after Attribute:

  • Milliseconds as number.

This is only relevant if you have things like css transition enabled, so that after the above resize events are fired, subsequent events are needed. It will fire the place-panel after the last resize/scroll event within the given time.

Tip Turn console-debug-log on (see configs) and check how events are working.

Explanation

What these helpers mainly do is to find all the dropdowns by the has-open-panel class and fire the place-panel event. But within the helper, things like performance optimisation are done: it searches once and places the panels multiple times.

Tooltip

<span data-controller="csedl-tooltip" data-panel-id="tooltip-123" data-delay="0.2">
    Text-with-tooltip
</span>
<div id="tooltip-123" class="hide tooltip-panel">
    <div id="arrow"></div>
    ... any content
</div>

makes a tooltip.

It adds the class tooltip-is-visible to the tooltip label while the tooltip is visible.

data-src attribute is working similar to dropdown

Rails Helpers

There is a corresponding rails gem, on GitLab

Stimulus Usage in stimulus-dropdown

This package uses Stimulus unconventionally to initialize and toggle external dropdown or tooltip panels (via data-panel-id) rather than managing child elements within the controller’s scope, as is typical in Stimulus documentation.

The same result could be achieved using MutationObserver and plain JavaScript.

Stimulus was chosen because this package is intended for use with Hotwire/Turbo where Stimulus already is installed. It has a modest footprint of just 10 KB. It also holds many configs for MutationObserver, especially for our exact purpose.

License

MIT