Skip to content

kucherenko-ae/event-delegator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Event Delegator

A tiny TypeScript library for DOM event delegation with powerful action dispatching to web components.

Features

  • 🚀 Lightweight - minimal footprint, no dependencies
  • 🎯 Event Delegation - efficient event handling using event delegation pattern
  • 🔧 Web Components - seamless integration with custom web components
  • 🏃 Performance - sync/async execution modes
  • 🛡️ TypeScript - full TypeScript support with type safety
  • 🔌 Interceptors - custom event handling logic

Installation

npm install @alexander.k/event-delegator

Quick Start

import { eventDelegator } from '@alexander.k/event-delegator'

// Initialize event delegation for click events
eventDelegator({
  events: ['click']
})

Configuration

eventDelegator({
  events: ['click', 'input', 'change'], // Events to listen for
  capture: true,                        // Use capture phase
  attributePrefix: 'data-ed-',         // Custom attribute prefix
  interceptors: [                      // Custom interceptors
    ({ target, method, params, element }) => {
      // Log all actions
      console.log(`Action: ${target} -> ${method}(${params})`)
      
      // Access triggering element when available
      if (element) {
        console.log('Triggered by:', element.tagName, element.id || element.className)
      }
      
      // Handle special cases
      if (target === 'location' && method === 'navigate') {
        // Custom navigation logic
        window.location.href = params
        return true // Prevent default handling
      }
      
      return false // Continue with default handling
    }
  ]
})

Action Syntax

Actions follow the pattern: -> selector/method/params

  • selector: CSS selector or component name
    • component-name - finds closest component with this tag name
    • #id - finds element by ID
    • .class - finds element by class
    • / - current component (closest custom element)
  • method: method name to call on the target element/component
  • params (optional): comma-separated parameters to pass to the method

Flags:

  • prevent - calls event.preventDefault()
  • stop - calls event.stopPropagation()
  • sync - executes actions sequentially (awaits each)
  • element - passes the triggering element as first parameter to methods

Events example

Bubbling Events

  • click, dblclick, contextmenu
  • input, change, submit, reset, select
  • keydown, keyup
  • pointerdown, pointerup
  • toggle

Non-bubbling Events

  • focusin, focusout
  • pointerenter, pointerleave

Usage Examples

Basic Component Method Call

Call the update method on the closest dynamic-section component:

<button data-ed-click="-> dynamic-section/update">Update Section</button>

Internal Component Method

Call a method within the current component (uses closest lookup):

<button data-ed-click="-> /open">Open</button>

Multiple Actions

Execute multiple actions in parallel (default) or sequentially (with sync flag):

<button data-ed-click="
  -> component-a/methodA
  -> component-b/methodB
  -> #specific-element/methodC
">Multiple Actions</button>

Flags usage

Use flags for event control and call multiple components:

<button data-ed-click="
  prevent, stop, sync
  -> dynamic-section/preload
  -> #dialog-modal/open
">Open Dialog</button>

Sequential Execution with sync Flag

Ensure actions are executed one after another, waiting for each to complete:

<button data-ed-click="
  sync
  -> data-loader/fetch
  -> chart-component/render
  -> notification/show
">Load and Display Data</button>

Element Access with element Flag

Pass the triggering element as the first parameter to methods:

<custom-form-component>
  <form data-ed-submit="prevent -> /submitForm">
    <!-- Checkbox state handling -->
    <input type="checkbox" data-ed-change="element -> /toggleDetailedForm">

    <!-- Notes -->
    <fieldset hidden>
      <textarea name="note_1"></textarea>
      <textarea name="note_2"></textarea>
      <!-- Any another fields -->
    </fieldset>

    <!-- Input validation on change -->
    <input
      type="email" 
      data-ed-input="element -> /validate/email" 
      placeholder="Enter email"
    >

    <button type="submit">Submit</button>
  </form>
</custom-form-component>

In your web component:

class CustomFormComponent extends HTMLElement {
  toggleDetailedForm = (triggerElement: Element) => {
    const input = triggerElement as HTMLInputElement

    console.log('Show detailed form: ', input.checked)

    // Handler
  }

  validate = (element: Element, type: string) => {
    const input = element as HTMLInputElement
    const value = input.value

    console.log(`Need to validate ${type}, current value: ${value}`)

    // Validator
  }

  submitForm = () => {
    console.log('Form submitting ...')

    // Submit logic
  }
}

Browser Support

  • Modern browsers with ES2018+ support
  • Custom Elements v1
  • Event delegation with capture/bubble phases

License

MIT

Contributing

Issues and pull requests are welcome on GitHub.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published