diff --git a/.claude/plans/player-api-implementation.md b/.claude/plans/player-api-implementation.md index 522bf4e7..56fa3be1 100644 --- a/.claude/plans/player-api-implementation.md +++ b/.claude/plans/player-api-implementation.md @@ -708,8 +708,8 @@ export function useMedia(): Media | null { return media; } -/** Register a media element (for Video/Audio primitives). Returns undefined if outside provider (standalone media). */ -export function useMediaRegistration(): Dispatch> | undefined { +/** Access the media attach setter for connecting a media element to the player. */ +export function useMediaAttach(): Dispatch> | undefined { const ctx = useContext(PlayerContext); return ctx?.setMedia; } @@ -725,7 +725,7 @@ Factory that creates typed provider and hooks. Update existing Video component t ``` packages/react/src/player/create-player.tsx (new) -packages/react/src/media/video.tsx (update - use useMediaRegistration) +packages/react/src/media/video.tsx (update - use useMediaAttach) packages/react/src/index.ts packages/react/src/player/tests/create-player.test.tsx (new) ``` @@ -809,14 +809,14 @@ export function createPlayer[]>( import type { Ref, VideoHTMLAttributes } from 'react'; import { useCallback } from 'react'; import { useComposedRefs } from '../utils/use-composed-refs'; -import { useMediaRegistration } from '../player/context'; +import { useMediaAttach } from '../player/context'; export interface VideoProps extends VideoHTMLAttributes { ref?: Ref | React.RefObject; } export function Video({ children, ref: refProp, ...props }: VideoProps): React.JSX.Element { - const setMedia = useMediaRegistration(); + const setMedia = useMediaAttach(); const attachRef = useCallback( (el: HTMLVideoElement): (() => void) | void => { @@ -1303,7 +1303,7 @@ UI primitives (PlayButton, VolumeSlider, etc.) need store access without knowing - `usePlayer()` — returns current state snapshot (untyped `Record`) - `usePlayer(selector)` — returns selected state via selector - `useMedia()` — returns current media element -- `useMediaRegistration()` — for Video/Audio primitives to register +- `useMediaAttach()` — for Video/Audio primitives to attach `createPlayer()` wraps this base with typed hooks for app code. diff --git a/internal/decisions/provider-attach.md b/internal/decisions/provider-attach.md new file mode 100644 index 00000000..1f0a7b72 --- /dev/null +++ b/internal/decisions/provider-attach.md @@ -0,0 +1,48 @@ +--- +status: decided +date: 2026-03-13 +--- + +# Provider Owns Media Attachment + +## Decision + +The provider (`` / React `Provider`) owns the `store.attach()` lifecycle. The container (`` / React `Container`) no longer discovers media or calls `store.attach()` — it registers itself with the provider via context and serves only as a layout reference element. + +Media and container elements register themselves with the provider through attach contexts — setter callbacks that flow downward from provider to descendants. The provider calls `store.attach({ media, container })` when it has a media element. As a fallback for plain `