From cfdbc4c55210361e0adbd325f9976f5383b70b16 Mon Sep 17 00:00:00 2001 From: Christian Pillsbury Date: Tue, 19 Aug 2025 14:04:00 -0500 Subject: [PATCH] refactor(react): Continue with component hooks rearchitecture. --- packages/core/media-store/src/factory.ts | 9 ++++++++- .../media-store/src/state-mediators/audible.ts | 6 ++++-- packages/react/react/src/components/MuteButton.tsx | 14 ++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/core/media-store/src/factory.ts b/packages/core/media-store/src/factory.ts index 5f89fd3c..c31fff11 100644 --- a/packages/core/media-store/src/factory.ts +++ b/packages/core/media-store/src/factory.ts @@ -1,4 +1,4 @@ -import { map, subscribeKeys } from 'nanostores'; +import { getKey, map, subscribeKeys } from 'nanostores'; export type StateOwners = { media?: any; @@ -118,6 +118,13 @@ export function createMediaStore({ return store.get(); }, + getKeys(keys: string[]) { + return keys.reduce((acc, k) => { + acc[k] = getKey(store, k); + return acc; + }, {} as { [k: string]: any }); + }, + subscribeKeys(keys: string[], callback: (state: any) => void) { subscribeKeys(store, keys, callback); }, diff --git a/packages/core/media-store/src/state-mediators/audible.ts b/packages/core/media-store/src/state-mediators/audible.ts index 5748a54c..88ac1c18 100644 --- a/packages/core/media-store/src/state-mediators/audible.ts +++ b/packages/core/media-store/src/state-mediators/audible.ts @@ -30,7 +30,9 @@ export const audible = { mediaEvents: ['volumechange'], actions: { /** @TODO Refactor me to play more nicely with side effects that don't/can't correlate with set() API (CJP) */ - mediavolumerequest: ({ detail }: Pick, 'detail'> = { detail: 0 }) => +detail, + mediavolumerequest: ( + { detail }: Pick, 'detail'> = { detail: 0 }, + ) => +detail, }, }, // NOTE: This could be (re)implemented as "derived state" in some manner (e.g. selectors but also other patterns/conventions) if preferred. (CJP) @@ -45,4 +47,4 @@ export const audible = { }, mediaEvents: ['volumechange'], }, -}; \ No newline at end of file +}; diff --git a/packages/react/react/src/components/MuteButton.tsx b/packages/react/react/src/components/MuteButton.tsx index b7dbdec5..d1523333 100644 --- a/packages/react/react/src/components/MuteButton.tsx +++ b/packages/react/react/src/components/MuteButton.tsx @@ -2,7 +2,7 @@ import { useMediaDispatch, useMediaSelector } from '@vjs-10/react-media-store'; import * as React from 'react'; import type { ElementType, PropsWithChildren } from 'react'; -type DefaultMuteButtonState = { mediaVolumeLevel: string }; +type DefaultMuteButtonState = { volumeLevel: string; muted: boolean }; type DefaultMuteButtonEventCallbacks = { onmediamuterequest: (event: Pick) => void; onmediaunmuterequest: (event: Pick) => void; @@ -44,9 +44,17 @@ export const useMuteButtonProps = ( state: ReturnType, ) => { return { - ...props, + /** data attributes/props */ ['data-muted']: state.muted, ['data-volume-level']: state.volumeLevel, + /** @TODO Need another state provider in core for i18n (CJP) */ + /** aria attributes/props */ + role: 'button', + ['aria-label']: state.muted ? 'unmute' : 'mute', + /** tooltip */ + ['data-tooltip']: state.muted ? 'Unmute' : 'Mute', + /** external props spread last to allow for overriding */ + ...props, }; }; @@ -61,6 +69,8 @@ export const renderMuteButton = (