# wrAffix

> Stick-on-scroll directive. Combines native CSS `position: sticky` with an `IntersectionObserver` sentinel that toggles a `wr-affix--active` class while pinned — so you can style the stuck state (shadow, background, shrink) without a scroll listener.

Source: https://ngwr.dev/reference/directives/affix  
Kind: Directive

## Import

```angular-ts
import { WrAffix } from 'ngwr/affix';
```

## Usage

```angular-html
<header wrAffix [wrAffixOffsetTop]="0" (wrAffixChange)="onAffix($event)">
  …
</header>
```

```scss
/* Style the stuck state via the .wr-affix--active modifier */
header.wr-affix--active {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  background: var(--wr-color-white);
}
```

## Demo (scroll inside the box)

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `[wrAffix]` | Apply to any element. Adds `position: sticky` + an IntersectionObserver sentinel that toggles `wr-affix--active` while the element is pinned. | `directive` | `—` |
| `[wrAffixOffsetTop]` | Pixels from the top of the scroll container when stuck. Drives both `style.top` and the observer threshold — and it is live: an `IntersectionObserver` cannot change its `rootMargin`, so a new offset builds a new observer rather than letting the pinned position and the state flip apart. | `number` | `0` |
| `(wrAffixChange)` | Emits `true` on stick, `false` on release — transitions only. The observer reports STATE, so it delivers an entry the moment it starts watching and can repeat one the host is already in; a repeat is swallowed rather than emitted. | `boolean` | `—` |
| `.wr-affix--active` | Class added to the host while pinned. Hook your active-state styles here. | `class` | `—` |
