@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 = falseAll 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-dependentExample
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
hideclass on the panel and places the panel using floating-ui. - When the panel is open, the
has-open-panelclass is added to the button, otherwise it is removed. - Adds functionality to close all panels when clicking outside a panel.
- When a
data-srcattribute 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.dataDropdownPersistset to true.
Flexibility
The functions of this package are intended to give flexibility on various ways building a dropdown.
- Stimulus Controller with Rails Helper
- Stimulus with Svelte component
- Example: Stimulus controller on example app
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-classmust be set toposition: absolute;. - The class
hidemust be set todisplay: none;.
Options
- If there is an element with ID
arrowinside the dropdown panel, it is treated as described on floating-ui. - The
data-placementattribute on the panel can be used to control positioning, see floating-ui/placements.
Events
Events on the button element:
place-panelplaces the panel, and, if present, the arrow element, byfloating-ui.
Events the panel element:
closecloses the panel.place-melike place-panel on the button.
Event Triggers on the button element:
before-open-panelafter-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:
scrolltriggered byscrollEvent of the given element.resize-observertriggered 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
