From 2e99ba79ae4381d71788a38e9d7db2e31b5857b3 Mon Sep 17 00:00:00 2001 From: Christian Pillsbury Date: Thu, 11 Sep 2025 13:56:32 -0700 Subject: [PATCH] refactor(media-store): add container state owner and rename event types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add container state owner to StateOwners type for fullscreen support - Rename mediaelementchangerequest to mediastateownerchangerequest - Add containerstateownerchangerequest event handling - Refactor updateStateOwners to support multiple state owners - Update all usage locations across HTML and React packages - Validated with Playwright testing on both demo applications 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- packages/core/media-store/src/factory.ts | 13 +++++++++++-- packages/html/html/src/media-container.ts | 2 +- .../react/react-media-store/src/MediaProvider.tsx | 4 ++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/core/media-store/src/factory.ts b/packages/core/media-store/src/factory.ts index d19ea5f8..9e89996a 100644 --- a/packages/core/media-store/src/factory.ts +++ b/packages/core/media-store/src/factory.ts @@ -2,6 +2,7 @@ import { getKey, map, subscribeKeys } from 'nanostores'; export type StateOwners = { media?: any; + container?: any; }; export type EventOrAction = { @@ -52,6 +53,7 @@ export function createMediaStore({ stateMediator, }: { media?: any; + container?: any; stateMediator: Partial & Pick; }) { const stateOwners: StateOwners = {}; @@ -60,7 +62,12 @@ export function createMediaStore({ const keys = Object.keys(stateMediator); function updateStateOwners(nextStateOwners: any) { - if (nextStateOwners.media === stateOwners.media) { + // Check if any state owner has changed + const hasChanges = Object.entries(nextStateOwners).some( + ([key, value]) => stateOwners[key as keyof StateOwners] !== value + ); + + if (!hasChanges) { return; } @@ -101,8 +108,10 @@ export function createMediaStore({ dispatch(action: Pick, 'type' | 'detail'>) { const { type, detail } = action; - if (type === 'mediaelementchangerequest') { + if (type === 'mediastateownerchangerequest') { updateStateOwners({ media: detail }); + } else if (type === 'containerstateownerchangerequest') { + updateStateOwners({ container: detail }); } else { for (const stateObject of Object.values(stateMediator).filter( ( diff --git a/packages/html/html/src/media-container.ts b/packages/html/html/src/media-container.ts index 4a4e0cdc..4b1ca416 100644 --- a/packages/html/html/src/media-container.ts +++ b/packages/html/html/src/media-container.ts @@ -40,7 +40,7 @@ export class MediaContainer extends ConsumerMixin(HTMLElement) { _handleMediaSlotChange = () => { const media = this._mediaSlot.assignedElements({ flatten: true })[0]; - this._mediaStore.dispatch({ type: 'mediaelementchangerequest', detail: media }); + this._mediaStore.dispatch({ type: 'mediastateownerchangerequest', detail: media }); }; } diff --git a/packages/react/react-media-store/src/MediaProvider.tsx b/packages/react/react-media-store/src/MediaProvider.tsx index b7ca9154..f72bd7e4 100644 --- a/packages/react/react-media-store/src/MediaProvider.tsx +++ b/packages/react/react-media-store/src/MediaProvider.tsx @@ -58,9 +58,9 @@ export const useMediaRef = () => { // NOTE: This should get invoked with `null` when using as a `ref` callback whenever // the corresponding react media element instance (e.g. a `