refactor(react): Continue with component hooks rearchitecture.

This commit is contained in:
Christian Pillsbury
2025-09-08 17:15:40 -07:00
committed by Christian Pillsbury
parent ba8797cd21
commit cfdbc4c552
3 changed files with 24 additions and 5 deletions
+8 -1
View File
@@ -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);
},
@@ -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<CustomEvent<any>, 'detail'> = { detail: 0 }) => +detail,
mediavolumerequest: (
{ detail }: Pick<CustomEvent<any>, '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'],
},
};
};
@@ -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<CustomEvent, 'type'>) => void;
onmediaunmuterequest: (event: Pick<CustomEvent, 'type'>) => void;
@@ -44,9 +44,17 @@ export const useMuteButtonProps = (
state: ReturnType<typeof useMuteButtonState>,
) => {
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 = (
<button
{...props}
onClick={() => {
/** @ts-ignore */
if (props.disabled) return;
if (state.muted) {
state.requestUnmute();
} else {