# dom-observer

Fire an event whenever a configured element mutates.


```html
<div>
  <section>
    <dom-observer target-ref=":scope + details"></dom-observer>
    <details id="do-watched">
      <summary>Toggle me — mutates the "open" attribute</summary>
      <p>Toggling this
        fired <code>dom-observer-change</code>.</p>
    </details>
    <output></output>
  </section>
  <quark-sheet>
    section {
      @on dom-observer-change {
        output { content: "#{event.detail.mutations.length} mutation(s), open: #{event.detail.target.open}"; }
      }
    }
  </quark-sheet>
</div>
```


## Features

- **Mutation events** Fires `dom-observer-change` on target changes
- **Selector-based** `target-ref` resolves any element, anywhere
- **Waits for its target** No matching element yet? It watches for one
- **Fires once immediately** An empty-`mutations` fire on resolve lets
  listeners seed from current state
- **`<template>`-aware** Also observes a template's `.content` fragment

## Installation


`@excom/dom-observer` v0.1.4

```bash
pnpm add @excom/dom-observer
```

```bash
npm install @excom/dom-observer
```

```bash
yarn add @excom/dom-observer
```

### Import

```ts
import "@excom/dom-observer";
```



## Usage

Point `target-ref` at any selector, then react to `dom-observer-change`
with `<event-handler>` (or Quark).

```html
<event-handler listen-for="dom-observer-change" fire-event="watched-changed">
  <dom-observer target-ref="#watched"></dom-observer>
</event-handler>
```

### API Reference


#### Attributes

| Name | Surface | Type | Default | Values | Description |
| --- | --- | --- | --- | --- | --- |
| `target-ref` | option | `string` |  |  | CSS selector used to resolve the element to observe. Resolved against `document`. If no element matches at connect time, the element waits for one to appear. |
| `target-element` | state | `HTMLElement` |  |  | The currently observed target element (if any). |
| `target-finding-observer` | state | `MutationObserver` |  |  | Document-level observer used to wait for a target matching `target-ref` to appear. Disconnected as soon as the target is found. |
| `target-change-observer` | state | `MutationObserver` |  |  | Observer attached to the resolved `targetElement` (and to its `.content` fragment when the target is a `<template>`). |

#### Fires

| Name | Type | Description |
| --- | --- | --- |
| `dom-observer-change` | `DomObserverChangeEvent` (`CustomEvent & { type: "dom-observer-change"; detail: { target: Element; mutations: MutationRecord[]; }; bubbles: true; cancelable: true; composed: true }`) | Fires whenever the resolved target mutates, and once immediately (with `mutations: []`) as soon as the target is resolved so listeners can seed from current state. `mutations` is the `MutationRecord[]` from the underlying `MutationObserver` callback (empty on that first fire). |



### Examples

#### Waiting for the target to exist

If nothing matches `target-ref` at connect time, `<dom-observer>` watches
the document for a match and switches over automatically — no glue code:

```html
<dom-observer target-ref="article#late"></dom-observer>
```

#### Observing a `<template>`

A `<template>`'s authored content lives on its `.content`
`DocumentFragment`, not as DOM descendants of the `<template>` itself.
`<dom-observer>` observes both, so mutations to either surface through the
same event stream:

```html
<template id="rows">
  <li>seed</li>
</template>
<dom-observer target-ref="#rows"></dom-observer>
```

## Release notes

### 0.1.1 (2026-09-23)

- Ship only dist (and declared extras) in the npm tarball; drop build logs, tests and sources
