import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/en/functional/Classes/EventRef - Reactive Event Manager'/>

# EventRef Class

A reactive event listener manager that simplifies attaching and detaching events to DOM elements or the `window` object. It automatically updates subscriptions when the target element (provided as a Vue `Ref`) changes.

Includes automatic re-binding of listeners during dynamic element changes and full integration with the Vue lifecycle.

## Key Features

- **Reactivity** — automatic updates when the element `Ref` changes.
- **Multi-type Support** — listen to multiple event types simultaneously.
- **Automatic Cleanup** — efficient memory management via the reactivity system.

## Initialization

Creates a new `EventRef` instance. The class automatically synchronizes event listeners with the state of the passed Vue `ref`. If the target element changes, `DesignConstructorAbstract` automatically rebinds the event.

### Generic Constraints

- `E extends ElementOrWindow` — type of the target element (e.g., `HTMLElement`, `Window`, or `Document`).
- `O extends Event` — type of the event object (e.g., `MouseEvent`, `KeyboardEvent`).
- `D extends Record<string, any>` — type of custom data (`detail`) associated with the event.

**Parameters:**
- `elementSelector?: RefOrNormal<ElementOrString<E> | undefined>` — target element or selector (can be reactive).
- `elementSelectorControl?: RefOrNormal<ElementOrString<HTMLElement>>` — control element. If it is removed from the DOM, listening stops.
- `type: string | string[] = ['click']` — event type or array of types.
- `listener?: EventListenerDetail<O, D>` — handler function.
- `options?: EventOptions` — listener options (`capture`, `passive`, `once`).
- `detail?: D` — additional event data.

```typescript
import { EventRef } from '@dxtmisha/functional'
import { ref, onMounted, onUnmounted } from 'vue'

// 1. Simple initialization with Ref
const buttonRef = ref<HTMLButtonElement>()
const event = new EventRef(buttonRef, undefined, 'click', (e) => {
  console.log('Button clicked:', e.target)
})

// 2. Using multiple events and options
const scrollEvent = new EventRef(
  window, 
  undefined, 
  ['scroll', 'resize'], 
  () => console.log('Window changed'),
  { passive: true }
)

onMounted(() => {
  event.start()
  scrollEvent.start()
})

onUnmounted(() => {
  event.stop()
  scrollEvent.stop()
})
```

## Lifecycle & Control

Methods for controlling the activity of listeners.

- `start(): this` — Activates event listening. If the target element (`ref`) is not yet mounted, the listeners will be added automatically as soon as it appears.
- `stop(): this` — Deactivates listening and removes all handlers from the current element.
- `toggle(activity: boolean): this` — Enables or disables listening based on the provided value.
- `reset(): this` — Restarts listening. It is automatically called when key parameters (event type, options, etc.) change.

## State & Data Acquisition

Methods for checking the object's current status.

- `isActive(): boolean` — Returns `true` if event listening is currently active.
- `getElement(): E | undefined` — Returns the current DOM element or object on which the listeners are set.

## Configuration (Setters)

All methods in this group support method chaining and automatically update active listeners.

- `setElement(element: ElementOrString): this` — Dynamically changes the target element. When used in `EventRef`, it also supports reactive `ref`.
- `setElementControl(element: ElementOrString): this` — Sets a control element. If this element is removed from the DOM, event listening on the main element is automatically stopped (protection against memory leaks).
- `setType(type: string | string[]): this` — Updates the types of listened events (e.g., changes `click` to `dblclick`).
- `setListener(listener: Function): this` — Changes the event handler function without restarting the entire cycle.
- `setOptions(options: EventOptions): this` — Updates the listener options (`capture`, `passive`, `once`).
- `setDetail(detail: object): this` — Updates the custom data available within the handler.

## Actions

- `dispatch(detail?: object): this` — Programmatically triggers an event on the target element. If data is passed in `detail`, it will take precedence over those set via `setDetail`.

## Special Events

`EventRef` (via the base class `EventItem`) provides enhanced handling for certain event types:

### `resize`
Unlike the standard `resize` event, which only works on the `window` object, here it uses `ResizeObserver`. This allows tracking dimension changes for any specific DOM element.

### `scroll-sync`
An optimized version of the scroll event. It uses `requestAnimationFrame` to synchronize the handler call with the screen refresh rate, preventing "lag" during heavy calculations during scrolling.
