/**
* Tiny event-delegation helpers. Replace per-element `addEventListener` calls
* (which don't survive morph re-renders for nodes the diff creates) with one
* listener at the morph-root that dispatches via `closest()`.
*
* Three-tier listener model:
*
* - Tier 1 (bubbling events) — use `delegate()`.
* click, input, change, submit, mousedown/up, keydown/up, pointerdown/up/move,
* drag*, drop, contextmenu, wheel, copy/paste/cut, focusin/focusout.
*
* `delegate()` also auto-promotes the well-known non-bubbling event
* types (`focus`, `blur`, `scroll`, `load`, `error`, `mouseenter`,
* `mouseleave`) to the capture phase under the hood, so the call site
* looks identical for "interactive thing happens on a descendant"
* regardless of whether that event bubbles. Selector matching stays
* `closest()`-style — the same as for bubbling events — so a wrapper
* selector like `'.field-row'` still matches when the event fires on
* a descendant ``.
*
* - Tier 2 (explicit capture) — use `delegateCapture()`.
* The escape hatch for cases the auto-promotion list doesn't cover
* (custom non-bubbling events) or when you want capture-phase
* interception. Selector matching is `closest()`-style by default —
* the same walk-up as `delegate()`, and it passes the matched ancestor
* (not the raw target) to the handler — so a click on any descendant of
* the selected element climbs to it. Pass `{ match: 'direct' }` to opt
* into strict `matches()`-style matching (fire only when the event lands
* on the exact element the selector identifies).
*
* - Tier 3 (per-element instances / library-owned subtrees) — mark the
* host element with `data-morph-skip` and manage the library's
* lifecycle directly. No delegation helper applies.
*/
/**
* How the selector is matched against the event's target:
*
* - `'closest'` (the default for both helpers) — walk UP from `event.target`
* via `closest(selector)`, firing for the nearest matching ancestor inside
* `rootEl`. This is the delegation behavior you almost always want: a click
* on an icon inside a button fires the button's handler.
* - `'direct'` — strict `matches()` match: fire only when `event.target`
* itself matches the selector, with no walk-up.
*/
interface DelegateOptions {
match?: 'closest' | 'direct';
}
/**
* Delegation that "just works" for both bubbling and the common non-bubbling
* events. Installs ONE listener on `rootEl`; for known non-bubblers (see
* `NON_BUBBLING` above) the listener is registered on the capture phase so
* it actually reaches the target, otherwise on the bubble phase. Either way,
* matching walks up from `event.target` via `closest(selector)` and fires
* `handler(event, matched)` if the match is inside `rootEl`.
*
* Pass `{ match: 'direct' }` to fire only when `event.target` itself matches
* the selector (no walk-up); the default is `'closest'`.
*
* The generic `T` narrows the second handler argument to the expected element
* type — `delegate(root, 'click', 'button', (e, btn) => btn.value)`
* — so consumers can avoid casts. Defaults to `Element` for untyped calls.
*
* Returns a disposer that removes the listener.
*
* Usage (pseudo-code — see examples for live ones):
* delegate(rootEl, 'click', '[data-action="add"]', handlerFn);
* delegate(rootEl, 'focus', 'input', handlerFn); // auto-capture
*/
declare function delegate(rootEl: HTMLElement, type: string, selector: string, handler: (event: Event, target: T) => void, options?: DelegateOptions): () => void;
/**
* Capture-phase delegation — the escape hatch for custom non-bubbling events
* (ones `delegate()`'s auto-promotion list doesn't know about) and for
* capture-phase interception (run before any descendant's bubble-phase
* handler). Reaches descendants of `rootEl` that match `selector` regardless
* of how many times the diff has rebuilt them.
*
* Selector matching is `closest()`-style by default — the same walk-up as
* `delegate()`, and it passes the matched ancestor (not the raw target) to
* the handler — so a click on any descendant of the selected element climbs
* to it. Pass `{ match: 'direct' }` to opt into strict `matches()`-style
* matching (fire only when the event lands on the exact element the selector
* identifies, with no walk-up).
*
* The generic `T` narrows the second handler argument to the expected element
* type, mirroring `delegate()`. Defaults to `Element` for untyped calls.
*
* Usage (pseudo-code — see examples for live ones):
* delegateCapture(rootEl, 'focus', 'input, textarea', handlerFn);
* delegateCapture(rootEl, 'click', '.exact', handlerFn, { match: 'direct' });
*/
declare function delegateCapture(rootEl: HTMLElement, type: string, selector: string, handler: (event: Event, target: T) => void, options?: DelegateOptions): () => void;
export { type DelegateOptions as D, delegateCapture as a, delegate as d };