mirror of
https://github.com/zoriya/v10.git
synced 2026-08-05 13:48:14 +00:00
feat(react): add fullscreen button component
Implement React fullscreen button with native React patterns: - useFullscreenButtonState hook for media store integration - useFullscreenButtonProps hook for element attribute management - renderFullscreenButton function for button rendering - Connected component via toConnectedComponent factory - Explicit enter/exit methods matching HTML implementation - Proper accessibility and data attributes Provides consistent fullscreen functionality across HTML and React platforms using shared state definition from media-store. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
Christian Pillsbury
co-authored by
Claude
parent
63a340213f
commit
7d819dfcd9
@@ -0,0 +1,89 @@
|
||||
import {
|
||||
shallowEqual,
|
||||
useMediaSelector,
|
||||
useMediaStore,
|
||||
} from '@vjs-10/react-media-store';
|
||||
import * as React from 'react';
|
||||
import { toConnectedComponent } from '../utils/component-factory';
|
||||
import { fullscreenButtonStateDefinition } from '@vjs-10/media-store';
|
||||
|
||||
export const useFullscreenButtonState = (_props: any) => {
|
||||
const mediaStore = useMediaStore();
|
||||
/** @TODO Fix type issues with hooks (CJP) */
|
||||
const mediaState = useMediaSelector(
|
||||
fullscreenButtonStateDefinition.stateTransform,
|
||||
shallowEqual,
|
||||
);
|
||||
|
||||
const methods = React.useMemo(
|
||||
() => fullscreenButtonStateDefinition.createRequestMethods(mediaStore.dispatch),
|
||||
[mediaStore],
|
||||
);
|
||||
|
||||
return {
|
||||
fullscreen: mediaState.fullscreen,
|
||||
requestEnterFullscreen: methods.requestEnterFullscreen,
|
||||
requestExitFullscreen: methods.requestExitFullscreen,
|
||||
} as const;
|
||||
};
|
||||
|
||||
export type useFullscreenButtonState = typeof useFullscreenButtonState;
|
||||
export type FullscreenButtonState = ReturnType<useFullscreenButtonState>;
|
||||
|
||||
export const useFullscreenButtonProps = (
|
||||
props: React.PropsWithChildren<{ [k: string]: any }>,
|
||||
state: ReturnType<typeof useFullscreenButtonState>,
|
||||
) => {
|
||||
const baseProps: Record<string, any> = {
|
||||
/** @TODO Need another state provider in core for i18n (CJP) */
|
||||
/** aria attributes/props */
|
||||
role: 'button',
|
||||
['aria-label']: state.fullscreen ? 'exit fullscreen' : 'enter fullscreen',
|
||||
/** tooltip */
|
||||
['data-tooltip']: state.fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen',
|
||||
/** external props spread last to allow for overriding */
|
||||
...props,
|
||||
};
|
||||
|
||||
// Handle boolean data attribute: present with empty string when true, absent when false
|
||||
if (state.fullscreen) {
|
||||
baseProps['data-fullscreen'] = '';
|
||||
}
|
||||
|
||||
return baseProps;
|
||||
};
|
||||
|
||||
export type useFullscreenButtonProps = typeof useFullscreenButtonProps;
|
||||
type FullscreenButtonProps = ReturnType<useFullscreenButtonProps>;
|
||||
|
||||
export const renderFullscreenButton = (
|
||||
props: FullscreenButtonProps,
|
||||
state: FullscreenButtonState,
|
||||
) => {
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
onClick={() => {
|
||||
/** @ts-ignore */
|
||||
if (props.disabled) return;
|
||||
if (state.fullscreen) {
|
||||
state.requestExitFullscreen();
|
||||
} else {
|
||||
state.requestEnterFullscreen();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export type renderFullscreenButton = typeof renderFullscreenButton;
|
||||
|
||||
export const FullscreenButton = toConnectedComponent(
|
||||
useFullscreenButtonState,
|
||||
useFullscreenButtonProps,
|
||||
renderFullscreenButton,
|
||||
'FullscreenButton',
|
||||
);
|
||||
export default FullscreenButton;
|
||||
@@ -7,4 +7,5 @@ export { Video, MediaElementVideo } from './components/Video';
|
||||
// New hook-style components
|
||||
export { PlayButton } from './components/PlayButton';
|
||||
export { MuteButton } from './components/MuteButton';
|
||||
export { VolumeRange } from './components/VolumeRange';
|
||||
export { VolumeRange } from './components/VolumeRange';
|
||||
export { FullscreenButton } from './components/FullscreenButton';
|
||||
Reference in New Issue
Block a user