feat(react): implement duration display component

Add React duration display component using VJS-10 hook-style patterns:
- Native React component using media store hooks
- Uses duration display state definition from media-store
- Minimal implementation rendering single span element
- Follows toConnectedComponent pattern for consistency

Component renders formatted duration (e.g., "4:32") without styling or
ARIA attributes, providing a clean foundation for duration display.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Christian Pillsbury
2025-09-12 15:59:15 -07:00
committed by Christian Pillsbury
co-authored by Claude
parent e35dd44be8
commit c5b659f449
2 changed files with 66 additions and 1 deletions
@@ -0,0 +1,64 @@
import {
shallowEqual,
useMediaSelector,
useMediaStore,
} from '@vjs-10/react-media-store';
import * as React from 'react';
import { toConnectedComponent } from '../utils/component-factory';
import { durationDisplayStateDefinition } from '@vjs-10/media-store';
export const useDurationDisplayState = (_props: any) => {
const mediaStore = useMediaStore();
/** @TODO Fix type issues with hooks (CJP) */
const mediaState = useMediaSelector(
durationDisplayStateDefinition.stateTransform,
shallowEqual,
);
// Duration display is read-only, no request methods needed
return {
duration: mediaState.duration,
isValidDuration: mediaState.isValidDuration,
formattedDuration: mediaState.formattedDuration,
durationPhrase: mediaState.durationPhrase,
} as const;
};
export type useDurationDisplayState = typeof useDurationDisplayState;
export type DurationDisplayState = ReturnType<useDurationDisplayState>;
export const useDurationDisplayProps = (
props: React.PropsWithChildren<{ [k: string]: any }>,
state: ReturnType<typeof useDurationDisplayState>,
) => {
const baseProps: Record<string, any> = {
/** external props spread last to allow for overriding */
...props,
};
return baseProps;
};
export type useDurationDisplayProps = typeof useDurationDisplayProps;
type DurationDisplayProps = ReturnType<useDurationDisplayProps>;
export const renderDurationDisplay = (
props: DurationDisplayProps,
state: DurationDisplayState,
) => {
return (
<span {...props}>
{state.formattedDuration}
</span>
);
};
export type renderDurationDisplay = typeof renderDurationDisplay;
export const DurationDisplay = toConnectedComponent(
useDurationDisplayState,
useDurationDisplayProps,
renderDurationDisplay,
'DurationDisplay',
);
export default DurationDisplay;
+2 -1
View File
@@ -9,4 +9,5 @@ export { MediaContainer, useMediaContainerRef } from './components/MediaContaine
export { PlayButton } from './components/PlayButton';
export { MuteButton } from './components/MuteButton';
export { VolumeRange } from './components/VolumeRange';
export { FullscreenButton } from './components/FullscreenButton';
export { FullscreenButton } from './components/FullscreenButton';
export { DurationDisplay } from './components/DurationDisplay';