'use client'; import { BufferingIndicatorCore, BufferingIndicatorDataAttrs } from '@videojs/core'; import { logMissingFeature, selectPlayback } from '@videojs/core/dom'; import type { ForwardedRef } from 'react'; import { forwardRef, useState, useSyncExternalStore } from 'react'; import { usePlayer } from '../../player/context'; import type { UIComponentProps } from '../../utils/types'; import { renderElement } from '../../utils/use-render'; export interface BufferingIndicatorProps extends UIComponentProps<'div', BufferingIndicatorCore.State>, BufferingIndicatorCore.Props {} /** * Displays a buffering indicator when media is waiting for data. * * Visibility is delayed (default 500ms) to avoid flashing on quick buffers. * * @example * ```tsx * * * * * ( *
{state.visible && }
* )} * /> * ``` */ export const BufferingIndicator = forwardRef(function BufferingIndicator( componentProps: BufferingIndicatorProps, forwardedRef: ForwardedRef ) { const { render, className, style, delay, ...elementProps } = componentProps; const playback = usePlayer(selectPlayback); const [core] = useState(() => new BufferingIndicatorCore()); core.setProps({ delay }); if (playback) core.update(playback); const state = useSyncExternalStore( (cb) => core.state.subscribe(cb), () => core.state.current, () => core.state.current ); if (!playback) { if (__DEV__) logMissingFeature('BufferingIndicator', 'playback'); return null; } return renderElement( 'div', { render, className, style }, { state, stateAttrMap: BufferingIndicatorDataAttrs, ref: [forwardedRef], props: [elementProps], } ); }); export namespace BufferingIndicator { export type Props = BufferingIndicatorProps; export type State = BufferingIndicatorCore.State; }