# live-ticker-strip

Zero-dependency, horizontally-scrolling ticker strip for any live JSON feed — stock prices, lottery draws, exchange rates, anything that's a list of `label` / `value` pairs that updates on a timer. No React/Vue/framework required; works as a plain ES module.

## Install

```bash
npm install live-ticker-strip
```

Or straight from a CDN, no build step:

```html
<script type="module">
  import { LiveTicker } from "https://cdn.jsdelivr.net/npm/live-ticker-strip@1/+esm";
</script>
```

## Usage

```html
<div id="ticker"></div>
<link rel="stylesheet" href="node_modules/live-ticker-strip/src/style.css" />

<script type="module">
  import { LiveTicker } from "live-ticker-strip";

  const ticker = new LiveTicker({
    el: "#ticker",
    fetchUrl: "https://your-api.example.com/results",
    refreshMs: 60000,        // re-fetch every 60s
    speedPxPerSec: 60,       // scroll speed
    mapItems: (json) =>
      json.data.map((row) => ({ label: row.name, value: row.result })),
  });

  ticker.start();
</script>
```

`mapItems` is the only thing you need to adapt per API — it takes whatever your endpoint returns and turns it into `{ label, value }` items. Everything else (polling, rendering, seamless-loop scrolling) is handled for you.

## Options

| Option | Type | Default | Description |
|---|---|---|---|
| `el` | `string \| HTMLElement` | — | Container to render into (required) |
| `fetchUrl` | `string` | — | Endpoint to poll (required) |
| `mapItems` | `(json) => Array<{label, value}>` | passthrough | Transforms the raw response into ticker items |
| `renderItem` | `(item) => string` | label + value spans | Customize the HTML for a single item |
| `refreshMs` | `number` | `60000` | Poll interval |
| `speedPxPerSec` | `number` | `60` | Scroll speed |
| `gapPx` | `number` | `48` | Spacing between items |
| `direction` | `"left" \| "right"` | `"left"` | Scroll direction |
| `pauseOnHover` | `boolean` | `true` | Pause animation while the mouse is over the strip |
| `fetchOptions` | `RequestInit` | `{}` | Passed straight to `fetch()` (headers, credentials, etc.) |

## Events

The container element dispatches two `CustomEvent`s:

- `lts:update` — fired after each successful fetch, `event.detail` is the mapped items array
- `lts:error` — fired if a fetch fails, `event.detail` is the error

```js
ticker.container.addEventListener("lts:update", (e) => console.log(e.detail));
```

## Methods

- `start()` — begin polling + animating
- `stop()` — pause polling + animation (keeps current content)
- `refresh()` — force an immediate re-fetch
- `destroy()` — fully tear down and clear the container

## Accessibility

Respects `prefers-reduced-motion: reduce` (animation is disabled, content stays in place). Consider giving the container `aria-live="off"` and `role="marquee"` if the scrolling content isn't essential to page meaning.

## License

MIT — built by [BlogHub](https://altosxcloud.com).
