# Moving highlight

One background that slides to the row under the pointer, the focus or the selection.

Package: @reuse-sh/interactions

## Principles

These are the rules to keep when you adapt this library. The code is one way to keep them. An adaptation on any framework must keep every one.

- Measure the real rows. The background takes its size and place from the row itself, also inside scaled containers.

- Let the keyboard lead. Focus moves the background like the pointer does, and keyboard focus wins while it is active.

- Keep selection apart. In selected mode it stays on the selected row, and a second highlight on the same root can follow the pointer.

- Follow layout changes. Resizes and content changes move it to the row's new place.

- Slide near, fade far. Nearby rows slide in 150 ms, distant ones fade out and back in, and reduced motion snaps.

- Skip disabled rows. Disabled and hidden rows never take the highlight.

## Install

```bash
npm install @reuse-sh/interactions
```

## Integration notes

- Mark rows with data-reuse-row and the selected row with data-current.

- Two highlights can share a root: one with mode "selected" for the active row, one with mode "hover" for the pointer.

- The controller measures the real elements. It does not need a menu library.

- Destroy removes the background and restores the styles the controller set.

## API

- `createMovingHighlight(root, options?)`: Adds one background that moves between the rows inside root. Returns refresh and destroy.

- `mode`: "hover" follows the pointer and focus and rests on the selected row. "selected" stays on the selected row and moves only when the selection changes. "hover" by default.

- `rowSelector, selectedSelector`: Which elements are rows, [data-reuse-row] by default, and which one is selected: data-current, aria-selected or data-highlighted.

- `className`: Added to the background element. Use it to tell two highlights on one root apart.

- `MovingHighlight`: The React wrapper around the same controller. highlightClassName sets the background's class.

## Browser JavaScript

```js
import { createMovingHighlight } from "@reuse-sh/interactions";
import "@reuse-sh/interactions/styles.css";

// <nav class="menu">
//   <a data-reuse-row data-current href="/">Overview</a>
//   <a data-reuse-row href="/examples">Examples</a>
// </nav>
const highlight = createMovingHighlight(document.querySelector(".menu"));

// Later, when the menu leaves the page
highlight.destroy();
```

## React

```tsx
import { MovingHighlight } from "@reuse-sh/interactions/react";
import "@reuse-sh/interactions/styles.css";

export function Menu({ current }) {
  return (
    <MovingHighlight className="menu">
      <a data-reuse-row data-current={current === "/" ? "" : undefined} href="/">Overview</a>
      <a data-reuse-row data-current={current === "/examples" ? "" : undefined} href="/examples">Examples</a>
    </MovingHighlight>
  );
}
```

## Agent workflow

1. Inspect the project and read the installed package's types and stylesheet.

2. Reuse the native controller. Use the React adapter only in a React surface.

3. Adapt styles and data connections to the project. Keep every principle above. Do not recreate the gesture or state engine.

4. Connect destroy and unsubscribe callbacks to the owner lifecycle.

5. Verify keyboard access, pointer/touch behavior, resize, empty/one-item states, errors, reduced motion, and teardown where applicable.

6. Report the actual checks and remaining browser/device limits.

## Source

https://github.com/reuse-sh/reuse/tree/main/packages/interactions/src

License: MIT for original library code. Preserve dependency and asset license notices.
