ElementManager is a utility component for automatic element discovery and management. It supports both single selector mode (backwards compatible) and multiple selector groups for organizing different types of elements. Perfect for building handler components like TooltipHandler, ModalManager, etc.
These are static HTML elements with data-test attributes.
These buttons are created dynamically via JavaScript. ElementManager automatically discovers them and adds event listeners via the elements Map. Click any dynamic button to see its individual click count update!
These are actual Svelte UI components with data-test attributes,
demonstrating ElementManager's ability to discover elements within components.
ElementManager now supports multiple selector groups in a single instance. This demo shows
element discovery by type using the new selectors prop.
<ElementManager
selectors={{
buttons: '[data-type="button"]',
inputs: '[data-type="input"]',
spans: '[data-type="span"]'
}}
bind:elements={elementGroups}
onElementAdded={(el, data, group) => {
// Handle element addition for this group
}}
>
<!-- Each group can be handled differently -->
<!-- ButtonHandler elements={elementGroups.buttons} />
<!-- InputHandler elements={elementGroups.inputs} />
<!-- SpanHandler elements={elementGroups.spans} -->
</ElementManager>Open browser dev tools to see console warnings for these ElementManager instances:
This ElementManager uses an empty selector, which should trigger a warning in DEV mode.
selector="" This ElementManager uses a broad selector that may impact performance.
selector="div" <ElementManager
selectors={{
tooltips: "[data-tooltip]"
}}
bind:elements={elementGroups}
/>
<TooltipHandler elements={elementGroups.tooltips} /><ElementManager
selectors={{
buttons: "button[data-action]",
inputs: "input[data-validate]",
forms: "form[data-submit]"
}}
bind:elements={elementGroups}
onElementAdded={(el, data, group) => {
// Set up group-specific handling
data.groupType = group;
}}
>
<!-- Each group can be processed differently -->
</ElementManager><ElementManager
selectors={{
interactive: "[data-interactive]"
}}
bind:elements={elementGroups}
onElementAdded={(el, data, group) => {
data.clickHandler = () => {
// Handle element click
};
el.addEventListener('click', data.clickHandler);
}}
onElementRemoved={(el, data, group) => {
if (data.clickHandler) {
el.removeEventListener('click', data.clickHandler);
}
}}
/><ElementManager
selectors={{
editable: "[contenteditable]"
}}
observerOptions={{
childList: true,
characterData: true,
subtree: true,
attributeFilter: ['contenteditable']
}}
bind:elements={elementGroups}
/>