# StoreController

Reactive controller for subscribing to store state in HTML custom elements

## Import

```ts
import { StoreController } from "@videojs/store/html";
```

`StoreController` is a reactive controller for accessing store state and actions in custom elements. It accepts a store instance or a context, resolving the store automatically.

**Without selector** – returns the store instance directly. Does NOT subscribe to changes. Use this to access store actions.

```ts
class VolumeControl extends HTMLElement {
  #store = new StoreController(this, storeSource);

  handleClick() {
    this.#store.value.setVolume(0.5);
  }
}
```

**With selector** – returns the selected value and subscribes to changes. Triggers a host update when the selected value changes (using shallow equality).

```ts
class PlayButton extends HTMLElement {
  #playback = new StoreController(this, storeSource, selectPlayback);

  render() {
    const playback = this.#playback.value;
    // Re-renders when playback state changes
  }
}
```

### StoreController vs PlayerController vs SnapshotController

| | `StoreController` | [`PlayerController`](https://videojs.org/docs/framework/html/reference/api/player-controller) | [`SnapshotController`](https://videojs.org/docs/framework/html/reference/api/snapshot-controller) |
| --- | --- | --- | --- |
| **Input** | Any store or context | Player store context | `State` container |
| **Typed to** | Generic store | Player features | Raw state |
| **Use case** | General-purpose store access | Player UI elements | Low-level state subscription |

[`PlayerController`](https://videojs.org/docs/framework/html/reference/api/player-controller) is a typed wrapper around `StoreController` scoped to the player store. For player UI, prefer `PlayerController`. Use `StoreController` when working with a custom store outside the player system.

When you pass a selector, `StoreController` internally creates a [`SnapshotController`](https://videojs.org/docs/framework/html/reference/api/snapshot-controller) on the store’s `$state` container. Without a selector, no subscription is created – you get the store instance for imperative access to actions.

## API Reference

### Without Selector

`new StoreController<Store extends AnyStore, Result = Store>(host, source)`

#### Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `host` (required) | `{ addController(controller: ReactiveController): void; removeController(controller: ReactiveController): void; requestUpdate(): void; updateComplete: Promise<boolean> } & HTMLElement` | — | The host element that owns this controller. |
| `source` (required) | `Store \| Context<unknown, Store>` | — | Store instance or context to resolve the store from. |

#### Return Value

| Property | Type |
| --- | --- |
| `value` | `Result` |

### With Selector

`new StoreController<Store extends AnyStore, Result = Store>(host, source, selector)`

#### Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `host` (required) | `{ addController(controller: ReactiveController): void; removeController(controller: ReactiveController): void; requestUpdate(): void; updateComplete: Promise<boolean> } & HTMLElement` | — | The host element that owns this controller. |
| `source` (required) | `Store \| Context<unknown, Store>` | — | Store instance or context to resolve the store from. |
| `selector` (required) | `{ (state: Store['state']): Result; displayName?: string }` | — | Derives a value from the store state. |

#### Return Value

| Property | Type |
| --- | --- |
| `value` | `Result` |

---

HTML documentation: https://videojs.org/docs/framework/html/llms.txt
All documentation: https://videojs.org/llms.txt
