@remotion/player 4.0.172 → 4.0.173

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,6 +47,7 @@ export type PlayerProps<Schema extends AnyZodObject, Props> = {
47
47
  readonly posterFillMode?: PosterFillMode;
48
48
  readonly bufferStateDelayInMilliseconds?: number;
49
49
  readonly hideControlsWhenPointerDoesntMove?: boolean | number;
50
+ readonly overflowVisible?: boolean;
50
51
  } & CompProps<Props> & PropsIfHasProps<Schema, Props>;
51
52
  export declare const componentOrNullIfLazy: <Props>(props: CompProps<Props>) => ComponentType<Props> | null;
52
53
  /**
@@ -22,7 +22,7 @@ const componentOrNullIfLazy = (props) => {
22
22
  return null;
23
23
  };
24
24
  exports.componentOrNullIfLazy = componentOrNullIfLazy;
25
- const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, ...componentProps }, ref) => {
25
+ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, ...componentProps }, ref) => {
26
26
  if (typeof window !== 'undefined') {
27
27
  // eslint-disable-next-line react-hooks/rules-of-hooks
28
28
  (0, react_1.useLayoutEffect)(() => {
@@ -140,7 +140,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
140
140
  const actualInputProps = (0, react_1.useMemo)(() => inputProps !== null && inputProps !== void 0 ? inputProps : {}, [inputProps]);
141
141
  return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(EmitterProvider_js_1.PlayerEmitterProvider, { currentPlaybackRate: currentPlaybackRate, children: (0, jsx_runtime_1.jsx)(PlayerUI_js_1.default, { ref: rootRef, posterFillMode: posterFillMode, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: actualInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
142
142
  ? clickToPlay
143
- : Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), showPosterWhenBuffering: Boolean(showPosterWhenBuffering), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove }) }) }) }) }));
143
+ : Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), showPosterWhenBuffering: Boolean(showPosterWhenBuffering), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, overflowVisible: overflowVisible }) }) }) }) }));
144
144
  };
145
145
  const forward = react_1.forwardRef;
146
146
  /**
@@ -1,4 +1,4 @@
1
- import type { MouseEventHandler, ReactNode } from 'react';
1
+ import type { MouseEventHandler, ReactNode, SyntheticEvent } from 'react';
2
2
  import React from 'react';
3
3
  import type { usePlayer } from './use-player.js';
4
4
  import type { Size } from './utils/use-element-size.js';
@@ -42,6 +42,6 @@ export declare const Controls: React.FC<{
42
42
  readonly containerRef: React.RefObject<HTMLDivElement>;
43
43
  readonly buffering: boolean;
44
44
  readonly hideControlsWhenPointerDoesntMove: boolean | number;
45
- readonly onPointerUp: React.PointerEventHandler<HTMLDivElement> | undefined;
45
+ readonly onPointerDown: ((ev: PointerEvent | SyntheticEvent) => void) | undefined;
46
46
  readonly onDoubleClick: MouseEventHandler<HTMLDivElement> | undefined;
47
47
  }>;
@@ -47,11 +47,13 @@ const controlsRow = {
47
47
  alignItems: 'center',
48
48
  justifyContent: 'center',
49
49
  userSelect: 'none',
50
+ WebkitUserSelect: 'none',
50
51
  };
51
52
  const leftPartStyle = {
52
53
  display: 'flex',
53
54
  flexDirection: 'row',
54
55
  userSelect: 'none',
56
+ WebkitUserSelect: 'none',
55
57
  alignItems: 'center',
56
58
  };
57
59
  const xSpacer = {
@@ -64,7 +66,7 @@ const flex1 = {
64
66
  flex: 1,
65
67
  };
66
68
  const fullscreen = {};
67
- const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, hideControlsWhenPointerDoesntMove, onPointerUp, onDoubleClick, }) => {
69
+ const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, hideControlsWhenPointerDoesntMove, onPointerDown, onDoubleClick, }) => {
68
70
  var _a, _b;
69
71
  const playButtonRef = (0, react_1.useRef)(null);
70
72
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
@@ -158,19 +160,19 @@ const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolumeContr
158
160
  }, [showPlaybackRateControl]);
159
161
  const ref = (0, react_1.useRef)(null);
160
162
  const flexRef = (0, react_1.useRef)(null);
161
- const onPointerUpIfContainer = (0, react_1.useCallback)((e) => {
163
+ const onPointerDownIfContainer = (0, react_1.useCallback)((e) => {
162
164
  // Only if pressing the container
163
165
  if (e.target === ref.current || e.target === flexRef.current) {
164
- onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp(e);
166
+ onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(e);
165
167
  }
166
- }, [onPointerUp]);
168
+ }, [onPointerDown]);
167
169
  const onDoubleClickIfContainer = (0, react_1.useCallback)((e) => {
168
170
  // Only if pressing the container
169
171
  if (e.target === ref.current || e.target === flexRef.current) {
170
172
  onDoubleClick === null || onDoubleClick === void 0 ? void 0 : onDoubleClick(e);
171
173
  }
172
174
  }, [onDoubleClick]);
173
- return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, style: containerCss, onPointerUp: onPointerUpIfContainer, onDoubleClick: onDoubleClickIfContainer, children: [(0, jsx_runtime_1.jsxs)("div", { ref: flexRef, style: controlsRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftPartStyle, children: [(0, jsx_runtime_1.jsx)("button", { ref: playButtonRef, type: "button", style: PlaybackrateControl_js_1.playerButtonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? ((0, jsx_runtime_1.jsx)(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: player.playing })) : ((_b = renderPlayPauseButton({
175
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, style: containerCss, onPointerDown: onPointerDownIfContainer, onDoubleClick: onDoubleClickIfContainer, children: [(0, jsx_runtime_1.jsxs)("div", { ref: flexRef, style: controlsRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftPartStyle, children: [(0, jsx_runtime_1.jsx)("button", { ref: playButtonRef, type: "button", style: PlaybackrateControl_js_1.playerButtonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? ((0, jsx_runtime_1.jsx)(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: player.playing })) : ((_b = renderPlayPauseButton({
174
176
  playing: player.playing,
175
177
  isBuffering: buffering,
176
178
  })) !== null && _b !== void 0 ? _b : ((0, jsx_runtime_1.jsx)(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: player.playing }))) }), showVolumeControls ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsx)(MediaVolumeSlider_js_1.MediaVolumeSlider, { displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsxs)("div", { style: timeLabel, children: [(0, format_time_js_1.formatTime)(frame / fps), " / ", (0, format_time_js_1.formatTime)(durationInFrames / fps)] }), (0, jsx_runtime_1.jsx)("div", { style: xSpacer })] }), (0, jsx_runtime_1.jsx)("div", { style: flex1 }), playbackRates && canvasSize && ((0, jsx_runtime_1.jsx)(PlaybackrateControl_js_1.PlaybackrateControl, { canvasSize: canvasSize, playbackRates: playbackRates })), playbackRates && supportsFullscreen && allowFullscreen ? ((0, jsx_runtime_1.jsx)("div", { style: xSpacer })) : null, (0, jsx_runtime_1.jsx)("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? ((0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', title: isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', style: PlaybackrateControl_js_1.playerButtonStyle, onClick: isFullscreen
@@ -21,6 +21,7 @@ const KNOB_SIZE = 12;
21
21
  const VERTICAL_PADDING = 4;
22
22
  const containerStyle = {
23
23
  userSelect: 'none',
24
+ WebkitUserSelect: 'none',
24
25
  paddingTop: VERTICAL_PADDING,
25
26
  paddingBottom: VERTICAL_PADDING,
26
27
  boxSizing: 'border-box',
@@ -42,5 +42,6 @@ declare const _default: React.ForwardRefExoticComponent<{
42
42
  readonly posterFillMode: PosterFillMode;
43
43
  readonly bufferStateDelayInMilliseconds: number;
44
44
  readonly hideControlsWhenPointerDoesntMove: number | boolean;
45
+ readonly overflowVisible: boolean;
45
46
  } & React.RefAttributes<PlayerRef>>;
46
47
  export default _default;
@@ -40,7 +40,7 @@ if (reactVersion === '0') {
40
40
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
41
41
  }
42
42
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
43
- const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove, }, ref) => {
43
+ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove, overflowVisible, }, ref) => {
44
44
  var _a, _b, _c;
45
45
  const config = remotion_1.Internals.useUnsafeVideoConfig();
46
46
  const video = remotion_1.Internals.useVideo();
@@ -298,14 +298,20 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
298
298
  ]);
299
299
  const VideoComponent = video ? video.component : null;
300
300
  const outerStyle = (0, react_1.useMemo)(() => {
301
- return (0, calculate_scale_js_1.calculateOuterStyle)({ canvasSize, config, style });
302
- }, [canvasSize, config, style]);
301
+ return (0, calculate_scale_js_1.calculateOuterStyle)({ canvasSize, config, style, overflowVisible });
302
+ }, [canvasSize, config, overflowVisible, style]);
303
303
  const outer = (0, react_1.useMemo)(() => {
304
- return (0, calculate_scale_js_1.calculateOuter)({ config, layout, scale });
305
- }, [config, layout, scale]);
304
+ return (0, calculate_scale_js_1.calculateOuter)({ config, layout, scale, overflowVisible });
305
+ }, [config, layout, overflowVisible, scale]);
306
306
  const containerStyle = (0, react_1.useMemo)(() => {
307
- return (0, calculate_scale_js_1.calculateContainerStyle)({ canvasSize, config, layout, scale });
308
- }, [canvasSize, config, layout, scale]);
307
+ return (0, calculate_scale_js_1.calculateContainerStyle)({
308
+ canvasSize,
309
+ config,
310
+ layout,
311
+ scale,
312
+ overflowVisible,
313
+ });
314
+ }, [canvasSize, config, layout, overflowVisible, scale]);
309
315
  const onError = (0, react_1.useCallback)((error) => {
310
316
  player.pause();
311
317
  // Pay attention to `this context`
@@ -336,7 +342,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
336
342
  requestFullscreen();
337
343
  }
338
344
  }, [exitFullscreen, isFullscreen, requestFullscreen]);
339
- const [handleClick, handleDoubleClick] = (0, use_click_prevention_on_double_click_js_1.useClickPreventionOnDoubleClick)(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
345
+ const { handlePointerDown, handleDoubleClick } = (0, use_click_prevention_on_double_click_js_1.useClickPreventionOnDoubleClick)(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
340
346
  (0, react_1.useEffect)(() => {
341
347
  if (shouldAutoplay) {
342
348
  player.play();
@@ -383,11 +389,11 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
383
389
  showPosterWhenBuffering && showBufferIndicator && player.isPlaying(),
384
390
  ].some(Boolean);
385
391
  const { left, top, width, height, ...outerWithoutScale } = outer;
386
- const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: outer, onPointerUp: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: (0, jsx_runtime_1.jsxs)("div", { style: containerStyle, className: player_css_classname_js_1.PLAYER_CSS_CLASSNAME, children: [VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_js_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.ClipComposition, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.CurrentScaleContext.Provider, { value: currentScale, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.props) !== null && _c !== void 0 ? _c : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) }) })) : null, shouldShowPoster && posterFillMode === 'composition-size' ? ((0, jsx_runtime_1.jsx)("div", { style: {
392
+ const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: outer, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: (0, jsx_runtime_1.jsxs)("div", { style: containerStyle, className: player_css_classname_js_1.PLAYER_CSS_CLASSNAME, children: [VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_js_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.ClipComposition, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.CurrentScaleContext.Provider, { value: currentScale, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.props) !== null && _c !== void 0 ? _c : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) }) })) : null, shouldShowPoster && posterFillMode === 'composition-size' ? ((0, jsx_runtime_1.jsx)("div", { style: {
387
393
  ...outerWithoutScale,
388
394
  width: config.width,
389
395
  height: config.height,
390
- }, onPointerUp: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }) }), shouldShowPoster && posterFillMode === 'player-size' ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onPointerUp: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_js_1.Controls, { fps: config.fps, durationInFrames: config.durationInFrames, player: player, containerRef: container, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, buffering: showBufferIndicator, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, onPointerUp: clickToPlay ? handleClick : undefined })) : null] }));
396
+ }, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }) }), shouldShowPoster && posterFillMode === 'player-size' ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_js_1.Controls, { fps: config.fps, durationInFrames: config.durationInFrames, player: player, containerRef: container, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, buffering: showBufferIndicator, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, onPointerDown: clickToPlay ? handlePointerDown : undefined })) : null] }));
391
397
  if (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense) {
392
398
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
393
399
  }
@@ -11,6 +11,7 @@ type ThumbnailProps<Schema extends AnyZodObject, Props extends Record<string, un
11
11
  compositionWidth: number;
12
12
  compositionHeight: number;
13
13
  fps: number;
14
+ overflowVisible?: boolean;
14
15
  errorFallback?: ErrorFallback;
15
16
  renderLoading?: RenderLoading;
16
17
  className?: string;
@@ -11,7 +11,7 @@ const emitter_context_js_1 = require("./emitter-context.js");
11
11
  const event_emitter_js_1 = require("./event-emitter.js");
12
12
  const SharedPlayerContext_js_1 = require("./SharedPlayerContext.js");
13
13
  const ThumbnailUI_js_1 = __importDefault(require("./ThumbnailUI.js"));
14
- const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback = () => '⚠️', renderLoading, ...componentProps }, ref) => {
14
+ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback = () => '⚠️', renderLoading, overflowVisible = false, ...componentProps }, ref) => {
15
15
  if (typeof window !== 'undefined') {
16
16
  // eslint-disable-next-line react-hooks/rules-of-hooks
17
17
  (0, react_1.useLayoutEffect)(() => {
@@ -44,7 +44,7 @@ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, com
44
44
  const passedInputProps = (0, react_1.useMemo)(() => {
45
45
  return inputProps !== null && inputProps !== void 0 ? inputProps : {};
46
46
  }, [inputProps]);
47
- return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineState, component: Component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: 0, initiallyMuted: true, children: (0, jsx_runtime_1.jsx)(emitter_context_js_1.ThumbnailEmitterContext.Provider, { value: emitter, children: (0, jsx_runtime_1.jsx)(ThumbnailUI_js_1.default, { ref: rootRef, className: className, errorFallback: errorFallback, inputProps: passedInputProps, renderLoading: renderLoading, style: style }) }) }) }));
47
+ return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineState, component: Component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: 0, initiallyMuted: true, children: (0, jsx_runtime_1.jsx)(emitter_context_js_1.ThumbnailEmitterContext.Provider, { value: emitter, children: (0, jsx_runtime_1.jsx)(ThumbnailUI_js_1.default, { ref: rootRef, className: className, errorFallback: errorFallback, inputProps: passedInputProps, renderLoading: renderLoading, style: style, overflowVisible: overflowVisible }) }) }) }));
48
48
  };
49
49
  const forward = react_1.forwardRef;
50
50
  /**
@@ -7,5 +7,6 @@ declare const _default: React.ForwardRefExoticComponent<{
7
7
  errorFallback: ErrorFallback;
8
8
  renderLoading: RenderLoading | undefined;
9
9
  className: string | undefined;
10
+ overflowVisible: boolean;
10
11
  } & React.RefAttributes<ThumbnailMethods>>;
11
12
  export default _default;
@@ -38,7 +38,7 @@ if (reactVersion === '0') {
38
38
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
39
39
  }
40
40
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
41
- const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className }, ref) => {
41
+ const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className, overflowVisible }, ref) => {
42
42
  var _a, _b;
43
43
  const config = remotion_1.Internals.useUnsafeVideoConfig();
44
44
  const video = remotion_1.Internals.useVideo();
@@ -70,19 +70,20 @@ const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, classNam
70
70
  }, [scale, thumbnail.emitter]);
71
71
  const VideoComponent = video ? video.component : null;
72
72
  const outerStyle = (0, react_1.useMemo)(() => {
73
- return (0, calculate_scale_js_1.calculateOuterStyle)({ config, style, canvasSize });
74
- }, [canvasSize, config, style]);
73
+ return (0, calculate_scale_js_1.calculateOuterStyle)({ config, style, canvasSize, overflowVisible });
74
+ }, [canvasSize, config, overflowVisible, style]);
75
75
  const outer = (0, react_1.useMemo)(() => {
76
- return (0, calculate_scale_js_1.calculateOuter)({ config, layout, scale });
77
- }, [config, layout, scale]);
76
+ return (0, calculate_scale_js_1.calculateOuter)({ config, layout, scale, overflowVisible });
77
+ }, [config, layout, overflowVisible, scale]);
78
78
  const containerStyle = (0, react_1.useMemo)(() => {
79
79
  return (0, calculate_scale_js_1.calculateContainerStyle)({
80
80
  canvasSize,
81
81
  config,
82
82
  layout,
83
83
  scale,
84
+ overflowVisible,
84
85
  });
85
- }, [canvasSize, config, layout, scale]);
86
+ }, [canvasSize, config, layout, overflowVisible, scale]);
86
87
  const onError = (0, react_1.useCallback)((error) => {
87
88
  // Pay attention to `this context`
88
89
  thumbnail.emitter.dispatchError(error);
@@ -13,21 +13,24 @@ export declare const calculateCanvasTransformation: ({ previewSize, compositionW
13
13
  compositionHeight: number;
14
14
  canvasSize: Size;
15
15
  }) => Layout;
16
- export declare const calculateOuterStyle: ({ config, style, canvasSize, }: {
16
+ export declare const calculateOuterStyle: ({ config, style, canvasSize, overflowVisible, }: {
17
17
  config: VideoConfig | null;
18
18
  style: React.CSSProperties | undefined;
19
19
  canvasSize: Size | null;
20
+ overflowVisible: boolean;
20
21
  }) => React.CSSProperties;
21
- export declare const calculateContainerStyle: ({ config, canvasSize, layout, scale, }: {
22
+ export declare const calculateContainerStyle: ({ config, canvasSize, layout, scale, overflowVisible, }: {
22
23
  config: VideoConfig | null;
23
24
  canvasSize: Size | null;
24
25
  layout: Layout | null;
25
26
  scale: number;
27
+ overflowVisible: boolean;
26
28
  }) => React.CSSProperties;
27
- export declare const calculateOuter: ({ layout, scale, config, }: {
29
+ export declare const calculateOuter: ({ layout, scale, config, overflowVisible, }: {
28
30
  layout: Layout | null;
29
31
  scale: number;
30
32
  config: VideoConfig | null;
33
+ overflowVisible: boolean;
31
34
  }) => {
32
35
  readonly width?: undefined;
33
36
  readonly height?: undefined;
@@ -45,6 +48,6 @@ export declare const calculateOuter: ({ layout, scale, config, }: {
45
48
  readonly position: "absolute";
46
49
  readonly left: number;
47
50
  readonly top: number;
48
- readonly overflow: "hidden";
51
+ readonly overflow: "hidden" | "visible";
49
52
  };
50
53
  export {};
@@ -26,13 +26,13 @@ const calculateCanvasTransformation = ({ previewSize, compositionWidth, composit
26
26
  };
27
27
  };
28
28
  exports.calculateCanvasTransformation = calculateCanvasTransformation;
29
- const calculateOuterStyle = ({ config, style, canvasSize, }) => {
29
+ const calculateOuterStyle = ({ config, style, canvasSize, overflowVisible, }) => {
30
30
  if (!config) {
31
31
  return {};
32
32
  }
33
33
  return {
34
34
  position: 'relative',
35
- overflow: 'hidden',
35
+ overflow: overflowVisible ? 'visible' : 'hidden',
36
36
  ...(0, calculate_player_size_js_1.calculatePlayerSize)({
37
37
  compositionHeight: config.height,
38
38
  compositionWidth: config.width,
@@ -44,7 +44,7 @@ const calculateOuterStyle = ({ config, style, canvasSize, }) => {
44
44
  };
45
45
  };
46
46
  exports.calculateOuterStyle = calculateOuterStyle;
47
- const calculateContainerStyle = ({ config, canvasSize, layout, scale, }) => {
47
+ const calculateContainerStyle = ({ config, canvasSize, layout, scale, overflowVisible, }) => {
48
48
  if (!config || !canvasSize || !layout) {
49
49
  return {};
50
50
  }
@@ -56,11 +56,11 @@ const calculateContainerStyle = ({ config, canvasSize, layout, scale, }) => {
56
56
  transform: `scale(${scale})`,
57
57
  marginLeft: layout.xCorrection,
58
58
  marginTop: layout.yCorrection,
59
- overflow: 'hidden',
59
+ overflow: overflowVisible ? 'visible' : 'hidden',
60
60
  };
61
61
  };
62
62
  exports.calculateContainerStyle = calculateContainerStyle;
63
- const calculateOuter = ({ layout, scale, config, }) => {
63
+ const calculateOuter = ({ layout, scale, config, overflowVisible, }) => {
64
64
  if (!layout || !config) {
65
65
  return {};
66
66
  }
@@ -73,7 +73,7 @@ const calculateOuter = ({ layout, scale, config, }) => {
73
73
  position: 'absolute',
74
74
  left: centerX,
75
75
  top: centerY,
76
- overflow: 'hidden',
76
+ overflow: overflowVisible ? 'visible' : 'hidden',
77
77
  };
78
78
  };
79
79
  exports.calculateOuter = calculateOuter;
@@ -19,7 +19,7 @@ export declare const PlayerInternals: {
19
19
  isFirstFrame: boolean;
20
20
  emitter: PlayerEmitter;
21
21
  playing: boolean;
22
- play: (e?: import("react").SyntheticEvent<Element, Event> | undefined) => void;
22
+ play: (e?: PointerEvent | import("react").SyntheticEvent<Element, Event> | undefined) => void;
23
23
  pause: () => void;
24
24
  pauseAndReturnToPlayStart: () => void;
25
25
  seek: (newFrame: number) => void;
@@ -7,7 +7,7 @@ type UsePlayerMethods = {
7
7
  isFirstFrame: boolean;
8
8
  emitter: PlayerEmitter;
9
9
  playing: boolean;
10
- play: (e?: SyntheticEvent) => void;
10
+ play: (e?: SyntheticEvent | PointerEvent) => void;
11
11
  pause: () => void;
12
12
  pauseAndReturnToPlayStart: () => void;
13
13
  seek: (newFrame: number) => void;
@@ -1,3 +1,7 @@
1
1
  import type { SyntheticEvent } from 'react';
2
- declare const useClickPreventionOnDoubleClick: (onClick: (e: SyntheticEvent) => void, onDoubleClick: () => void, doubleClickToFullscreen: boolean) => [(e: SyntheticEvent) => void, () => void];
2
+ type ReturnVal = {
3
+ handlePointerDown: (e: SyntheticEvent | PointerEvent) => void;
4
+ handleDoubleClick: () => void;
5
+ };
6
+ declare const useClickPreventionOnDoubleClick: (onClick: (e: PointerEvent | SyntheticEvent) => void, onDoubleClick: () => void, doubleClickToFullscreen: boolean) => ReturnVal;
3
7
  export { useClickPreventionOnDoubleClick };
@@ -9,7 +9,9 @@ const useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFu
9
9
  const api = (0, use_cancellable_promises_js_1.useCancellablePromises)();
10
10
  const handleClick = (0, react_1.useCallback)(async (e) => {
11
11
  // UnSupported double click on touch.(mobile)
12
- if (e.nativeEvent.pointerType === 'touch') {
12
+ if (e instanceof PointerEvent
13
+ ? e.pointerType === 'touch'
14
+ : e.nativeEvent.pointerType === 'touch') {
13
15
  onClick(e);
14
16
  return;
15
17
  }
@@ -29,16 +31,23 @@ const useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFu
29
31
  }
30
32
  }
31
33
  }, [api, onClick]);
34
+ const handlePointerDown = (0, react_1.useCallback)(() => {
35
+ document.addEventListener('pointerup', (newEvt) => {
36
+ handleClick(newEvt);
37
+ }, {
38
+ once: true,
39
+ });
40
+ }, [handleClick]);
32
41
  const handleDoubleClick = (0, react_1.useCallback)(() => {
33
42
  api.clearPendingPromises();
34
43
  onDoubleClick();
35
44
  }, [api, onDoubleClick]);
36
45
  const returnValue = (0, react_1.useMemo)(() => {
37
46
  if (!doubleClickToFullscreen) {
38
- return [onClick, () => undefined];
47
+ return { handlePointerDown: onClick, handleDoubleClick: () => undefined };
39
48
  }
40
- return [handleClick, handleDoubleClick];
41
- }, [doubleClickToFullscreen, handleClick, handleDoubleClick, onClick]);
49
+ return { handlePointerDown, handleDoubleClick };
50
+ }, [doubleClickToFullscreen, handleDoubleClick, handlePointerDown, onClick]);
42
51
  return returnValue;
43
52
  };
44
53
  exports.useClickPreventionOnDoubleClick = useClickPreventionOnDoubleClick;
@@ -253,14 +253,15 @@ var calculateCanvasTransformation = ({
253
253
  var calculateOuterStyle = ({
254
254
  config,
255
255
  style,
256
- canvasSize
256
+ canvasSize,
257
+ overflowVisible
257
258
  }) => {
258
259
  if (!config) {
259
260
  return {};
260
261
  }
261
262
  return {
262
263
  position: "relative",
263
- overflow: "hidden",
264
+ overflow: overflowVisible ? "visible" : "hidden",
264
265
  ...calculatePlayerSize({
265
266
  compositionHeight: config.height,
266
267
  compositionWidth: config.width,
@@ -275,7 +276,8 @@ var calculateContainerStyle = ({
275
276
  config,
276
277
  canvasSize,
277
278
  layout,
278
- scale
279
+ scale,
280
+ overflowVisible
279
281
  }) => {
280
282
  if (!config || !canvasSize || !layout) {
281
283
  return {};
@@ -288,13 +290,14 @@ var calculateContainerStyle = ({
288
290
  transform: `scale(${scale})`,
289
291
  marginLeft: layout.xCorrection,
290
292
  marginTop: layout.yCorrection,
291
- overflow: "hidden"
293
+ overflow: overflowVisible ? "visible" : "hidden"
292
294
  };
293
295
  };
294
296
  var calculateOuter = ({
295
297
  layout,
296
298
  scale,
297
- config
299
+ config,
300
+ overflowVisible
298
301
  }) => {
299
302
  if (!layout || !config) {
300
303
  return {};
@@ -308,7 +311,7 @@ var calculateOuter = ({
308
311
  position: "absolute",
309
312
  left: centerX,
310
313
  top: centerY,
311
- overflow: "hidden"
314
+ overflow: overflowVisible ? "visible" : "hidden"
312
315
  };
313
316
  };
314
317
 
@@ -1455,6 +1458,7 @@ var KNOB_SIZE2 = 12;
1455
1458
  var VERTICAL_PADDING = 4;
1456
1459
  var containerStyle = {
1457
1460
  userSelect: "none",
1461
+ WebkitUserSelect: "none",
1458
1462
  paddingTop: VERTICAL_PADDING,
1459
1463
  paddingBottom: VERTICAL_PADDING,
1460
1464
  boxSizing: "border-box",
@@ -1692,12 +1696,14 @@ var controlsRow = {
1692
1696
  width: "100%",
1693
1697
  alignItems: "center",
1694
1698
  justifyContent: "center",
1695
- userSelect: "none"
1699
+ userSelect: "none",
1700
+ WebkitUserSelect: "none"
1696
1701
  };
1697
1702
  var leftPartStyle = {
1698
1703
  display: "flex",
1699
1704
  flexDirection: "row",
1700
1705
  userSelect: "none",
1706
+ WebkitUserSelect: "none",
1701
1707
  alignItems: "center"
1702
1708
  };
1703
1709
  var xSpacer = {
@@ -1733,7 +1739,7 @@ var Controls = ({
1733
1739
  containerRef,
1734
1740
  buffering,
1735
1741
  hideControlsWhenPointerDoesntMove,
1736
- onPointerUp,
1742
+ onPointerDown,
1737
1743
  onDoubleClick
1738
1744
  }) => {
1739
1745
  const playButtonRef = useRef7(null);
@@ -1823,11 +1829,11 @@ var Controls = ({
1823
1829
  }, [showPlaybackRateControl]);
1824
1830
  const ref = useRef7(null);
1825
1831
  const flexRef = useRef7(null);
1826
- const onPointerUpIfContainer = useCallback6((e) => {
1832
+ const onPointerDownIfContainer = useCallback6((e) => {
1827
1833
  if (e.target === ref.current || e.target === flexRef.current) {
1828
- onPointerUp?.(e);
1834
+ onPointerDown?.(e);
1829
1835
  }
1830
- }, [onPointerUp]);
1836
+ }, [onPointerDown]);
1831
1837
  const onDoubleClickIfContainer = useCallback6((e) => {
1832
1838
  if (e.target === ref.current || e.target === flexRef.current) {
1833
1839
  onDoubleClick?.(e);
@@ -1836,7 +1842,7 @@ var Controls = ({
1836
1842
  return jsxs6("div", {
1837
1843
  ref,
1838
1844
  style: containerCss,
1839
- onPointerUp: onPointerUpIfContainer,
1845
+ onPointerDown: onPointerDownIfContainer,
1840
1846
  onDoubleClick: onDoubleClickIfContainer,
1841
1847
  children: [
1842
1848
  jsxs6("div", {
@@ -2024,7 +2030,7 @@ var useCancellablePromises = () => {
2024
2030
  var useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFullscreen) => {
2025
2031
  const api = useCancellablePromises();
2026
2032
  const handleClick = useCallback8(async (e) => {
2027
- if (e.nativeEvent.pointerType === "touch") {
2033
+ if (e instanceof PointerEvent ? e.pointerType === "touch" : e.nativeEvent.pointerType === "touch") {
2028
2034
  onClick(e);
2029
2035
  return;
2030
2036
  }
@@ -2043,18 +2049,25 @@ var useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFull
2043
2049
  }
2044
2050
  }
2045
2051
  }, [api, onClick]);
2052
+ const handlePointerDown = useCallback8(() => {
2053
+ document.addEventListener("pointerup", (newEvt) => {
2054
+ handleClick(newEvt);
2055
+ }, {
2056
+ once: true
2057
+ });
2058
+ }, [handleClick]);
2046
2059
  const handleDoubleClick = useCallback8(() => {
2047
2060
  api.clearPendingPromises();
2048
2061
  onDoubleClick();
2049
2062
  }, [api, onDoubleClick]);
2050
2063
  const returnValue = useMemo9(() => {
2051
2064
  if (!doubleClickToFullscreen) {
2052
- return [onClick, () => {
2065
+ return { handlePointerDown: onClick, handleDoubleClick: () => {
2053
2066
  return;
2054
- }];
2067
+ } };
2055
2068
  }
2056
- return [handleClick, handleDoubleClick];
2057
- }, [doubleClickToFullscreen, handleClick, handleDoubleClick, onClick]);
2069
+ return { handlePointerDown, handleDoubleClick };
2070
+ }, [doubleClickToFullscreen, handleDoubleClick, handlePointerDown, onClick]);
2058
2071
  return returnValue;
2059
2072
  };
2060
2073
 
@@ -2099,7 +2112,8 @@ var PlayerUI = ({
2099
2112
  showPlaybackRateControl,
2100
2113
  posterFillMode,
2101
2114
  bufferStateDelayInMilliseconds,
2102
- hideControlsWhenPointerDoesntMove
2115
+ hideControlsWhenPointerDoesntMove,
2116
+ overflowVisible
2103
2117
  }, ref) => {
2104
2118
  const config = Internals10.useUnsafeVideoConfig();
2105
2119
  const video = Internals10.useVideo();
@@ -2348,14 +2362,20 @@ var PlayerUI = ({
2348
2362
  ]);
2349
2363
  const VideoComponent = video ? video.component : null;
2350
2364
  const outerStyle = useMemo10(() => {
2351
- return calculateOuterStyle({ canvasSize, config, style });
2352
- }, [canvasSize, config, style]);
2365
+ return calculateOuterStyle({ canvasSize, config, style, overflowVisible });
2366
+ }, [canvasSize, config, overflowVisible, style]);
2353
2367
  const outer = useMemo10(() => {
2354
- return calculateOuter({ config, layout, scale });
2355
- }, [config, layout, scale]);
2368
+ return calculateOuter({ config, layout, scale, overflowVisible });
2369
+ }, [config, layout, overflowVisible, scale]);
2356
2370
  const containerStyle3 = useMemo10(() => {
2357
- return calculateContainerStyle({ canvasSize, config, layout, scale });
2358
- }, [canvasSize, config, layout, scale]);
2371
+ return calculateContainerStyle({
2372
+ canvasSize,
2373
+ config,
2374
+ layout,
2375
+ scale,
2376
+ overflowVisible
2377
+ });
2378
+ }, [canvasSize, config, layout, overflowVisible, scale]);
2359
2379
  const onError = useCallback9((error) => {
2360
2380
  player.pause();
2361
2381
  player.emitter.dispatchError(error);
@@ -2384,7 +2404,7 @@ var PlayerUI = ({
2384
2404
  requestFullscreen();
2385
2405
  }
2386
2406
  }, [exitFullscreen, isFullscreen, requestFullscreen]);
2387
- const [handleClick, handleDoubleClick] = useClickPreventionOnDoubleClick(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
2407
+ const { handlePointerDown, handleDoubleClick } = useClickPreventionOnDoubleClick(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
2388
2408
  useEffect11(() => {
2389
2409
  if (shouldAutoplay) {
2390
2410
  player.play();
@@ -2426,7 +2446,7 @@ var PlayerUI = ({
2426
2446
  children: [
2427
2447
  jsx10("div", {
2428
2448
  style: outer,
2429
- onPointerUp: clickToPlay ? handleClick : undefined,
2449
+ onPointerDown: clickToPlay ? handlePointerDown : undefined,
2430
2450
  onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
2431
2451
  children: jsxs7("div", {
2432
2452
  style: containerStyle3,
@@ -2451,7 +2471,7 @@ var PlayerUI = ({
2451
2471
  width: config.width,
2452
2472
  height: config.height
2453
2473
  },
2454
- onPointerUp: clickToPlay ? handleClick : undefined,
2474
+ onPointerDown: clickToPlay ? handlePointerDown : undefined,
2455
2475
  onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
2456
2476
  children: poster
2457
2477
  }) : null
@@ -2460,7 +2480,7 @@ var PlayerUI = ({
2460
2480
  }),
2461
2481
  shouldShowPoster && posterFillMode === "player-size" ? jsx10("div", {
2462
2482
  style: outer,
2463
- onPointerUp: clickToPlay ? handleClick : undefined,
2483
+ onPointerDown: clickToPlay ? handlePointerDown : undefined,
2464
2484
  onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
2465
2485
  children: poster
2466
2486
  }) : null,
@@ -2488,7 +2508,7 @@ var PlayerUI = ({
2488
2508
  buffering: showBufferIndicator,
2489
2509
  hideControlsWhenPointerDoesntMove,
2490
2510
  onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
2491
- onPointerUp: clickToPlay ? handleClick : undefined
2511
+ onPointerDown: clickToPlay ? handlePointerDown : undefined
2492
2512
  }) : null
2493
2513
  ]
2494
2514
  });
@@ -2794,6 +2814,7 @@ var PlayerFn = ({
2794
2814
  posterFillMode = "player-size",
2795
2815
  bufferStateDelayInMilliseconds,
2796
2816
  hideControlsWhenPointerDoesntMove = true,
2817
+ overflowVisible = false,
2797
2818
  ...componentProps
2798
2819
  }, ref) => {
2799
2820
  if (typeof window !== "undefined") {
@@ -2943,7 +2964,8 @@ var PlayerFn = ({
2943
2964
  alwaysShowControls,
2944
2965
  showPlaybackRateControl,
2945
2966
  bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds ?? 300,
2946
- hideControlsWhenPointerDoesntMove
2967
+ hideControlsWhenPointerDoesntMove,
2968
+ overflowVisible
2947
2969
  })
2948
2970
  })
2949
2971
  })
@@ -2999,7 +3021,7 @@ if (reactVersion2 === "0") {
2999
3021
  throw new Error(`Version ${reactVersion2} of "react" is not supported by Remotion`);
3000
3022
  }
3001
3023
  var doesReactVersionSupportSuspense2 = parseInt(reactVersion2, 10) >= 18;
3002
- var ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className: className2 }, ref) => {
3024
+ var ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className: className2, overflowVisible }, ref) => {
3003
3025
  const config = Internals13.useUnsafeVideoConfig();
3004
3026
  const video = Internals13.useVideo();
3005
3027
  const container = useRef11(null);
@@ -3030,19 +3052,20 @@ var ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className:
3030
3052
  }, [scale, thumbnail.emitter]);
3031
3053
  const VideoComponent = video ? video.component : null;
3032
3054
  const outerStyle = useMemo14(() => {
3033
- return calculateOuterStyle({ config, style, canvasSize });
3034
- }, [canvasSize, config, style]);
3055
+ return calculateOuterStyle({ config, style, canvasSize, overflowVisible });
3056
+ }, [canvasSize, config, overflowVisible, style]);
3035
3057
  const outer = useMemo14(() => {
3036
- return calculateOuter({ config, layout, scale });
3037
- }, [config, layout, scale]);
3058
+ return calculateOuter({ config, layout, scale, overflowVisible });
3059
+ }, [config, layout, overflowVisible, scale]);
3038
3060
  const containerStyle3 = useMemo14(() => {
3039
3061
  return calculateContainerStyle({
3040
3062
  canvasSize,
3041
3063
  config,
3042
3064
  layout,
3043
- scale
3065
+ scale,
3066
+ overflowVisible
3044
3067
  });
3045
- }, [canvasSize, config, layout, scale]);
3068
+ }, [canvasSize, config, layout, overflowVisible, scale]);
3046
3069
  const onError = useCallback11((error) => {
3047
3070
  thumbnail.emitter.dispatchError(error);
3048
3071
  }, [thumbnail.emitter]);
@@ -3115,6 +3138,7 @@ var ThumbnailFn = ({
3115
3138
  className: className2,
3116
3139
  errorFallback = () => "\u26A0\uFE0F",
3117
3140
  renderLoading,
3141
+ overflowVisible = false,
3118
3142
  ...componentProps
3119
3143
  }, ref) => {
3120
3144
  if (typeof window !== "undefined") {
@@ -3166,7 +3190,8 @@ var ThumbnailFn = ({
3166
3190
  errorFallback,
3167
3191
  inputProps: passedInputProps,
3168
3192
  renderLoading,
3169
- style
3193
+ style,
3194
+ overflowVisible
3170
3195
  })
3171
3196
  })
3172
3197
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/player",
3
- "version": "4.0.172",
3
+ "version": "4.0.173",
4
4
  "description": "Remotion Player",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/cjs/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  ],
29
29
  "license": "SEE LICENSE IN LICENSE.md",
30
30
  "dependencies": {
31
- "remotion": "4.0.172"
31
+ "remotion": "4.0.173"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": ">=16.8.0",