@remotion/studio 4.0.521 → 4.0.522

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.
Files changed (60) hide show
  1. package/dist/components/CanvasIfSizeIsAvailable.js +7 -0
  2. package/dist/components/CopyButton.js +7 -14
  3. package/dist/components/Editor.js +6 -5
  4. package/dist/components/EditorContent.js +1 -1
  5. package/dist/components/ElementInstallConfirmation.js +3 -1
  6. package/dist/components/FixComputedValueModal.js +20 -10
  7. package/dist/components/InspectorLocationCopy.js +10 -5
  8. package/dist/components/MenuBuildIndicator.js +7 -2
  9. package/dist/components/MenuCompositionName.js +62 -6
  10. package/dist/components/RenderModal/CliCopyButton.js +13 -27
  11. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +7 -4
  12. package/dist/components/SidebarCollapserControls.js +11 -5
  13. package/dist/components/SkillsSettings.js +9 -5
  14. package/dist/components/Splitter/SplitterContainer.js +63 -10
  15. package/dist/components/Splitter/SplitterContext.d.ts +3 -0
  16. package/dist/components/Splitter/SplitterContext.js +5 -1
  17. package/dist/components/Splitter/SplitterElement.js +11 -2
  18. package/dist/components/Splitter/SplitterHandle.d.ts +1 -0
  19. package/dist/components/Splitter/SplitterHandle.js +55 -25
  20. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  21. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  22. package/dist/components/Timeline/Timeline.js +15 -4
  23. package/dist/components/Timeline/TimelineDragHandler.js +9 -4
  24. package/dist/components/Timeline/TimelinePinchZoom.js +6 -30
  25. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +1 -7
  26. package/dist/components/Timeline/TimelineSequence.js +77 -12
  27. package/dist/components/Timeline/TimelineSequenceItem.js +12 -1
  28. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +13 -3
  29. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +168 -121
  30. package/dist/components/Timeline/TimelineSlider.js +1 -4
  31. package/dist/components/Timeline/TimelineWidthProvider.js +2 -5
  32. package/dist/components/Timeline/TimelineZoomControls.js +20 -20
  33. package/dist/components/Timeline/get-sequence-split-menu-item.d.ts +11 -0
  34. package/dist/components/Timeline/get-sequence-split-menu-item.js +55 -0
  35. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -2
  36. package/dist/components/Timeline/use-sequence-props-subscription.js +4 -10
  37. package/dist/components/TopPanel.js +3 -19
  38. package/dist/components/UpdatesSettings.js +9 -5
  39. package/dist/components/ZoomPersistor.js +6 -3
  40. package/dist/components/composition-menu-items.js +1 -1
  41. package/dist/esm/{chunk-emw4k5b0.js → chunk-3netyjd9.js} +4917 -4651
  42. package/dist/esm/internals.mjs +4917 -4651
  43. package/dist/esm/previewEntry.mjs +4895 -4629
  44. package/dist/esm/renderEntry.mjs +1 -1
  45. package/dist/helpers/copy-text.js +1 -2
  46. package/dist/helpers/use-copy-feedback.d.ts +4 -0
  47. package/dist/helpers/use-copy-feedback.js +19 -0
  48. package/dist/icons/copy.d.ts +5 -0
  49. package/dist/icons/copy.js +12 -0
  50. package/dist/state/canvas-ref.d.ts +1 -0
  51. package/dist/state/canvas-ref.js +2 -1
  52. package/dist/state/sidebar.d.ts +3 -0
  53. package/dist/state/sidebar.js +6 -1
  54. package/dist/state/timeline-zoom.d.ts +1 -1
  55. package/dist/state/timeline-zoom.js +3 -3
  56. package/dist/visual-controls/VisualControls.js +4 -0
  57. package/package.json +15 -15
  58. package/dist/esm/chunk-vkrvnx2h.js +0 -99378
  59. package/dist/helpers/use-max-media-duration.d.ts +0 -2
  60. package/dist/helpers/use-max-media-duration.js +0 -61
@@ -1,9 +1,42 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.SplitterContainer = exports.containerColumn = void 0;
4
37
  const jsx_runtime_1 = require("react/jsx-runtime");
5
38
  const player_1 = require("@remotion/player");
6
- const react_1 = require("react");
39
+ const react_1 = __importStar(require("react"));
7
40
  const timeline_1 = require("../../state/timeline");
8
41
  const SplitterContext_1 = require("./SplitterContext");
9
42
  const SplitterHandle_1 = require("./SplitterHandle");
@@ -21,8 +54,10 @@ exports.containerColumn = {
21
54
  height: 0,
22
55
  };
23
56
  const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFlex, maxFlexerSize, minFlexerSize, maxAntiFlexerSize, minAntiFlexerSize, id, }) => {
57
+ const parentLayout = (0, react_1.useContext)(SplitterContext_1.SplitterLayoutContext);
24
58
  const [initialTimelineFlex, persistFlex] = (0, timeline_1.useTimelineFlex)(id);
25
59
  const [flexValue, setFlexValue] = (0, react_1.useState)(initialTimelineFlex !== null && initialTimelineFlex !== void 0 ? initialTimelineFlex : defaultFlex);
60
+ const [collapsedDuringDrag, setCollapsedDuringDrag] = (0, react_1.useState)(null);
26
61
  const ref = (0, react_1.useRef)(null);
27
62
  const isDragging = (0, react_1.useRef)(false);
28
63
  const size = player_1.PlayerInternals.useElementSize(ref, {
@@ -46,6 +81,8 @@ const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFle
46
81
  const value = (0, react_1.useMemo)(() => {
47
82
  return {
48
83
  flexValue: effectiveFlexValue,
84
+ collapsedDuringDrag,
85
+ setCollapsedDuringDrag,
49
86
  ref,
50
87
  setFlexValue,
51
88
  isDragging,
@@ -62,6 +99,7 @@ const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFle
62
99
  };
63
100
  }, [
64
101
  defaultFlex,
102
+ collapsedDuringDrag,
65
103
  effectiveFlexValue,
66
104
  id,
67
105
  maxFlex,
@@ -74,14 +112,29 @@ const SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFle
74
112
  persistFlex,
75
113
  ref,
76
114
  ]);
77
- (0, react_1.useEffect)(() => {
78
- const frame = requestAnimationFrame(() => {
79
- player_1.PlayerInternals.updateAllElementsSizes();
80
- });
81
- return () => {
82
- cancelAnimationFrame(frame);
83
- };
84
- });
85
- return (jsx_runtime_1.jsx(SplitterContext_1.SplitterContext.Provider, { value: value, children: jsx_runtime_1.jsx("div", { ref: ref, style: orientation === 'horizontal' ? exports.containerColumn : containerRow, children: children }) }));
115
+ const childCount = react_1.default.Children.toArray(children).length;
116
+ const layout = (0, react_1.useMemo)(() => ({
117
+ parentLayout,
118
+ effectiveFlexValue,
119
+ collapsedDuringDrag,
120
+ orientation,
121
+ width: size === null || size === void 0 ? void 0 : size.width,
122
+ height: size === null || size === void 0 ? void 0 : size.height,
123
+ childCount,
124
+ }), [
125
+ parentLayout,
126
+ effectiveFlexValue,
127
+ collapsedDuringDrag,
128
+ orientation,
129
+ size === null || size === void 0 ? void 0 : size.width,
130
+ size === null || size === void 0 ? void 0 : size.height,
131
+ childCount,
132
+ ]);
133
+ const refreshSize = size === null || size === void 0 ? void 0 : size.refresh;
134
+ (0, react_1.useLayoutEffect)(() => {
135
+ // Remeasure this splitter when its own or an ancestor's layout changes.
136
+ refreshSize === null || refreshSize === void 0 ? void 0 : refreshSize();
137
+ }, [layout, refreshSize]);
138
+ return (jsx_runtime_1.jsx(SplitterContext_1.SplitterLayoutContext.Provider, { value: layout, children: jsx_runtime_1.jsx(SplitterContext_1.SplitterContext.Provider, { value: value, children: jsx_runtime_1.jsx("div", { ref: ref, style: orientation === 'horizontal' ? exports.containerColumn : containerRow, children: children }) }) }));
86
139
  };
87
140
  exports.SplitterContainer = SplitterContainer;
@@ -6,6 +6,8 @@ export type SplitterDragState = false | {
6
6
  export type SplitterOrientation = 'horizontal' | 'vertical';
7
7
  export type TSplitterContext = {
8
8
  flexValue: number;
9
+ collapsedDuringDrag: 'left' | 'right' | null;
10
+ setCollapsedDuringDrag: (side: 'left' | 'right' | null) => void;
9
11
  setFlexValue: React.Dispatch<React.SetStateAction<number>>;
10
12
  orientation: SplitterOrientation;
11
13
  ref: React.RefObject<HTMLDivElement | null>;
@@ -36,4 +38,5 @@ export declare const getClampedSplitterFlex: ({ flexValue, ...bounds }: Pick<TSp
36
38
  readonly flexValue: number;
37
39
  }) => number;
38
40
  export declare const SplitterContext: React.Context<TSplitterContext>;
41
+ export declare const SplitterLayoutContext: React.Context<object | null>;
39
42
  export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SplitterContext = exports.getClampedSplitterFlex = exports.getSplitterFlexBounds = void 0;
6
+ exports.SplitterLayoutContext = exports.SplitterContext = exports.getClampedSplitterFlex = exports.getSplitterFlexBounds = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const getSplitterFlexBounds = ({ availableSize, maxAntiFlexerSize, maxFlex, maxFlexerSize, minAntiFlexerSize, minFlex, minFlexerSize, }) => {
9
9
  if (availableSize === null || availableSize <= 0) {
@@ -21,6 +21,8 @@ const getClampedSplitterFlex = ({ flexValue, ...bounds }) => {
21
21
  exports.getClampedSplitterFlex = getClampedSplitterFlex;
22
22
  exports.SplitterContext = react_1.default.createContext({
23
23
  flexValue: 1,
24
+ collapsedDuringDrag: null,
25
+ setCollapsedDuringDrag: () => undefined,
24
26
  ref: { current: null },
25
27
  setFlexValue: () => undefined,
26
28
  isDragging: { current: false },
@@ -35,3 +37,5 @@ exports.SplitterContext = react_1.default.createContext({
35
37
  id: '--',
36
38
  persistFlex: () => undefined,
37
39
  });
40
+ // Propagate layout changes only through the affected splitter subtree.
41
+ exports.SplitterLayoutContext = react_1.default.createContext(null);
@@ -15,7 +15,9 @@ const SplitterElement = ({ children, type, sticky }) => {
15
15
  flex:
16
16
  // Multiply by 1000 because if flex values don't add up to at least 1, they will not fill up the screen
17
17
  (type === 'flexer' ? context.flexValue : 1 - context.flexValue) * 1000,
18
- display: 'flex',
18
+ display: context.collapsedDuringDrag === (type === 'flexer' ? 'left' : 'right')
19
+ ? 'none'
20
+ : 'flex',
19
21
  position: 'relative',
20
22
  overflow: 'hidden',
21
23
  flexDirection: 'column',
@@ -28,7 +30,14 @@ const SplitterElement = ({ children, type, sticky }) => {
28
30
  ? (minSize !== null && minSize !== void 0 ? minSize : undefined)
29
31
  : undefined,
30
32
  };
31
- }, [context.flexValue, context.orientation, maxSize, minSize, type]);
33
+ }, [
34
+ context.collapsedDuringDrag,
35
+ context.flexValue,
36
+ context.orientation,
37
+ maxSize,
38
+ minSize,
39
+ type,
40
+ ]);
32
41
  const stickStyle = (0, react_1.useMemo)(() => {
33
42
  return {
34
43
  position: 'absolute',
@@ -3,4 +3,5 @@ export declare const SPLITTER_HANDLE_SIZE = 3;
3
3
  export declare const SplitterHandle: React.FC<{
4
4
  readonly allowToCollapse: 'right' | 'left' | 'none';
5
5
  readonly onCollapse: () => void;
6
+ readonly onCollapseDuringDrag: ((side: 'left' | 'right' | null) => void) | null;
6
7
  }>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SplitterHandle = exports.SPLITTER_HANDLE_SIZE = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const player_1 = require("@remotion/player");
6
5
  const react_1 = require("react");
7
6
  const pointer_session_1 = require("../../helpers/pointer-session");
8
7
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
@@ -11,10 +10,14 @@ exports.SPLITTER_HANDLE_SIZE = 3;
11
10
  const containerRow = {
12
11
  height: exports.SPLITTER_HANDLE_SIZE,
13
12
  };
13
+ const collapsedContainer = {
14
+ width: 0,
15
+ height: 0,
16
+ };
14
17
  const containerColumn = {
15
18
  width: exports.SPLITTER_HANDLE_SIZE,
16
19
  };
17
- const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
20
+ const SplitterHandle = ({ allowToCollapse, onCollapse, onCollapseDuringDrag }) => {
18
21
  const context = (0, react_1.useContext)(SplitterContext_1.SplitterContext);
19
22
  if (!context) {
20
23
  throw new Error('Cannot find splitter context');
@@ -22,8 +25,13 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
22
25
  const ref = (0, react_1.useRef)(null);
23
26
  // Keep the latest props/context readable inside the long-lived pointerdown
24
27
  // listener without re-subscribing it on every render.
25
- const latest = (0, react_1.useRef)({ context, allowToCollapse, onCollapse });
26
- latest.current = { context, allowToCollapse, onCollapse };
28
+ const latest = (0, react_1.useRef)({
29
+ context,
30
+ allowToCollapse,
31
+ onCollapse,
32
+ onCollapseDuringDrag,
33
+ });
34
+ latest.current = { context, allowToCollapse, onCollapse, onCollapseDuringDrag };
27
35
  (0, react_1.useEffect)(() => {
28
36
  const { current } = ref;
29
37
  if (!current) {
@@ -75,41 +83,59 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
75
83
  }
76
84
  return newFlex;
77
85
  };
86
+ const getCollapsedSide = (ev) => {
87
+ const collapse = latest.current.allowToCollapse;
88
+ const unclamped = getNewValue(ev, false);
89
+ if (collapse === 'left' && unclamped < dragContext.minFlex / 2) {
90
+ return 'left';
91
+ }
92
+ if (collapse === 'right' &&
93
+ 1 - unclamped < (1 - dragContext.maxFlex) / 2) {
94
+ return 'right';
95
+ }
96
+ return null;
97
+ };
98
+ let lastFlex = startFlex;
99
+ let lastCollapsedSide = null;
78
100
  const onPointerMove = (ev) => {
101
+ var _a, _b;
79
102
  if (!dragContext.isDragging.current) {
80
103
  return;
81
104
  }
82
- dragContext.setFlexValue(getNewValue(ev, true));
83
- const collapse = latest.current.allowToCollapse;
84
- if (collapse === 'left') {
85
- const unclamped = getNewValue(ev, false);
86
- if (unclamped < dragContext.minFlex / 2) {
87
- endDrag === null || endDrag === void 0 ? void 0 : endDrag();
88
- latest.current.onCollapse();
89
- }
90
- }
91
- else if (collapse === 'right') {
92
- const unclamped = 1 - getNewValue(ev, false);
93
- if (unclamped < (1 - dragContext.maxFlex) / 2) {
94
- endDrag === null || endDrag === void 0 ? void 0 : endDrag();
95
- latest.current.onCollapse();
96
- }
97
- }
105
+ // Keep the handle mounted and captured until release, even while
106
+ // the panel is hidden, so moving inward can restore it.
107
+ lastCollapsedSide = getCollapsedSide(ev);
108
+ lastFlex = getNewValue(ev, true);
109
+ (_b = (_a = latest.current).onCollapseDuringDrag) === null || _b === void 0 ? void 0 : _b.call(_a, lastCollapsedSide);
110
+ dragContext.setCollapsedDuringDrag(lastCollapsedSide);
111
+ dragContext.setFlexValue(lastFlex);
98
112
  };
99
113
  endDrag = (0, pointer_session_1.startCapturedPointerSession)({
100
114
  event: e,
101
115
  captureTarget: current,
102
116
  onMove: onPointerMove,
103
117
  onEnd: (reason, endEvent) => {
118
+ var _a, _b;
104
119
  if ((reason === 'pointerup' || reason === 'buttons-released') &&
105
- endEvent &&
106
- dragContext.isDragging.current) {
107
- dragContext.persistFlex(getNewValue(endEvent, true));
120
+ endEvent) {
121
+ lastFlex = getNewValue(endEvent, true);
122
+ lastCollapsedSide = getCollapsedSide(endEvent);
123
+ }
124
+ // Capture loss and cancellation may have no usable coordinates.
125
+ // Commit the last displayed state instead of resetting the panel.
126
+ if (reason !== 'manual' && dragContext.isDragging.current) {
127
+ const savedFlex = lastCollapsedSide === null ? lastFlex : startFlex;
128
+ dragContext.setFlexValue(savedFlex);
129
+ dragContext.persistFlex(savedFlex);
130
+ if (lastCollapsedSide !== null) {
131
+ latest.current.onCollapse();
132
+ }
108
133
  }
134
+ (_b = (_a = latest.current).onCollapseDuringDrag) === null || _b === void 0 ? void 0 : _b.call(_a, null);
135
+ dragContext.setCollapsedDuringDrag(null);
109
136
  dragContext.isDragging.current = false;
110
137
  (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
111
138
  endDrag = null;
112
- player_1.PlayerInternals.updateAllElementsSizes();
113
139
  },
114
140
  });
115
141
  };
@@ -124,6 +150,10 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
124
150
  context.orientation === 'horizontal'
125
151
  ? 'remotion-splitter-horizontal'
126
152
  : 'remotion-splitter-vertical',
127
- ].join(' '), style: context.orientation === 'horizontal' ? containerRow : containerColumn }));
153
+ ].join(' '), style: context.collapsedDuringDrag !== null
154
+ ? collapsedContainer
155
+ : context.orientation === 'horizontal'
156
+ ? containerRow
157
+ : containerColumn }));
128
158
  };
129
159
  exports.SplitterHandle = SplitterHandle;
@@ -1,9 +1,10 @@
1
1
  import { type FC } from 'react';
2
- import type { EffectDefinition, JsxComponentIdentity, InteractivitySchema } from 'remotion';
2
+ import type { EffectDefinition, JsxComponentIdentity, InteractivitySchema, VideoConfigValues } from 'remotion';
3
3
  export declare const SubscribeToNodePaths: FC<{
4
4
  readonly overrideId: string;
5
5
  readonly componentIdentity: JsxComponentIdentity | null;
6
6
  readonly schema: InteractivitySchema;
7
7
  readonly getStack: () => string | null;
8
8
  readonly effects: readonly EffectDefinition<unknown>[];
9
+ readonly videoConfigValues: VideoConfigValues | null;
9
10
  }>;
@@ -5,7 +5,7 @@ const react_1 = require("react");
5
5
  const no_react_1 = require("remotion/no-react");
6
6
  const use_resolved_stack_react_to_change_1 = require("./use-resolved-stack-react-to-change");
7
7
  const use_sequence_props_subscription_1 = require("./use-sequence-props-subscription");
8
- const SubscribeToNodePaths = ({ overrideId, componentIdentity, schema, getStack, effects }) => {
8
+ const SubscribeToNodePaths = ({ overrideId, componentIdentity, schema, getStack, effects, videoConfigValues, }) => {
9
9
  const { resolvedLocation, stack, preferMappedNodePath } = (0, use_resolved_stack_react_to_change_1.useResolveStackAndReactToChange)(getStack, overrideId);
10
10
  const effectSubscriptions = (0, react_1.useMemo)(() => {
11
11
  return effects
@@ -22,6 +22,7 @@ const SubscribeToNodePaths = ({ overrideId, componentIdentity, schema, getStack,
22
22
  originalLocation: resolvedLocation,
23
23
  preferMappedNodePath,
24
24
  stack,
25
+ videoConfigValues,
25
26
  });
26
27
  return null;
27
28
  };
@@ -356,9 +356,20 @@ const TimelineInner = () => {
356
356
  timeline,
357
357
  ]);
358
358
  const durationInFrames = (_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 0;
359
+ const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
359
360
  const filtered = (0, react_1.useMemo)(() => {
360
- return timeline.filter((t) => (0, should_show_track_in_timeline_1.shouldShowTrackInTimeline)(t, durationInFrames));
361
- }, [durationInFrames, timeline]);
361
+ return timeline.filter((t) => {
362
+ // Moving outside the composition can reduce the displayed duration to
363
+ // zero. Keep the drag owner mounted until its pending edit is saved.
364
+ if (t.sequence.showInTimeline &&
365
+ t.nodePathInfo !== null &&
366
+ getDragOverrides(t.nodePathInfo.sequenceSubscriptionKey).from !==
367
+ undefined) {
368
+ return true;
369
+ }
370
+ return (0, should_show_track_in_timeline_1.shouldShowTrackInTimeline)(t, durationInFrames);
371
+ });
372
+ }, [durationInFrames, getDragOverrides, timeline]);
362
373
  // Keep `filtered` complete so a future toggle can show every programmatic
363
374
  // instance without recalculating the timeline or losing its instance index.
364
375
  const collapsed = (0, react_1.useMemo)(() => {
@@ -388,10 +399,10 @@ const TimelineInner = () => {
388
399
  if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewInteractive)) {
389
400
  return null;
390
401
  }
391
- return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
402
+ return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects, videoConfigValues: sequence.controls.videoConfigValues }, sequence.id));
392
403
  }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineLayerChildren_1.TimelineLayerChildrenProvider, { value: layerChildrenValue, children: jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: jsx_runtime_1.jsxs(TimelineVirtualization_1.TimelineVirtualizationProvider, { hasBeenCut: hasBeenCut, isStill: isStill, timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, {})) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
393
404
  jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
394
- jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, {}) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
405
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, {}) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, onCollapseDuringDrag: null, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
395
406
  jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
396
407
  ] }), children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
397
408
  jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null] }) })
@@ -80,6 +80,7 @@ const TimelineDragHandler = () => {
80
80
  });
81
81
  const { zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
82
82
  const { canvasContent, currentAssetMetadata } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
83
+ const videoId = video === null || video === void 0 ? void 0 : video.id;
83
84
  const containerStyle = (0, react_1.useMemo)(() => {
84
85
  var _a;
85
86
  var _b, _c, _d, _e;
@@ -90,16 +91,20 @@ const TimelineDragHandler = () => {
90
91
  const zoom = (0, get_timeline_max_zoom_1.getTimelineZoom)({
91
92
  durationInFrames,
92
93
  timelineViewportWidth: (_d = (_c = timelineSize === null || timelineSize === void 0 ? void 0 : timelineSize.width) !== null && _c !== void 0 ? _c : (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _d !== void 0 ? _d : 0,
93
- zoom: canvasContent.type === 'composition'
94
- ? ((_e = zoomMap[canvasContent.compositionId]) !== null && _e !== void 0 ? _e : null)
95
- : null,
94
+ zoom: videoId ? ((_e = zoomMap[videoId]) !== null && _e !== void 0 ? _e : null) : null,
96
95
  });
97
96
  return {
98
97
  ...container,
99
98
  width: (0, get_timeline_max_zoom_1.getTimelineWidth)({ durationInFrames, zoom }),
100
99
  height: TimelineTimeIndicators_1.TIMELINE_TIME_INDICATOR_HEIGHT,
101
100
  };
102
- }, [canvasContent, timelineSize === null || timelineSize === void 0 ? void 0 : timelineSize.width, video === null || video === void 0 ? void 0 : video.durationInFrames, zoomMap]);
101
+ }, [
102
+ canvasContent,
103
+ timelineSize === null || timelineSize === void 0 ? void 0 : timelineSize.width,
104
+ video === null || video === void 0 ? void 0 : video.durationInFrames,
105
+ videoId,
106
+ zoomMap,
107
+ ]);
103
108
  const hasPlayableContent = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ||
104
109
  ((canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'asset' &&
105
110
  (currentAssetMetadata === null || currentAssetMetadata === void 0 ? void 0 : currentAssetMetadata.asset) === canvasContent.asset);
@@ -18,7 +18,6 @@ const ZOOM_WHEEL_SENSITIVITY = 0.06;
18
18
  const TimelinePinchZoom = () => {
19
19
  const isVideoComposition = (0, is_current_selected_still_1.useIsVideoComposition)();
20
20
  const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
21
- const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
22
21
  const { zoom, setZoom } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
23
22
  const { editorZoomGestures } = (0, react_1.useContext)(editor_zoom_gestures_1.EditorZoomGesturesContext);
24
23
  const zoomRef = (0, react_1.useRef)(zoom);
@@ -51,9 +50,6 @@ const TimelinePinchZoom = () => {
51
50
  if (!videoConfig || videoConfig.durationInFrames < 2) {
52
51
  return;
53
52
  }
54
- if (!canvasContent || canvasContent.type !== 'composition') {
55
- return;
56
- }
57
53
  const scrollEl = timeline_refs_1.scrollableRef.current;
58
54
  if (!scrollEl) {
59
55
  return;
@@ -70,14 +66,8 @@ const TimelinePinchZoom = () => {
70
66
  else if (deltaMode === WheelEvent.DOM_DELTA_PAGE) {
71
67
  scaledDeltaY *= scrollEl.clientHeight;
72
68
  }
73
- setZoom(canvasContent.compositionId, (z) => z * Math.exp(-scaledDeltaY * ZOOM_WHEEL_SENSITIVITY), { anchorFrame: null, anchorContentX });
74
- }, [
75
- editorZoomGestures,
76
- isVideoComposition,
77
- videoConfig,
78
- canvasContent,
79
- setZoom,
80
- ]);
69
+ setZoom(videoConfig.id, (z) => z * Math.exp(-scaledDeltaY * ZOOM_WHEEL_SENSITIVITY), { anchorFrame: null, anchorContentX });
70
+ }, [editorZoomGestures, isVideoComposition, videoConfig, setZoom]);
81
71
  const supportsWebKitPinch = typeof window !== 'undefined' && 'GestureEvent' in window;
82
72
  (0, react_1.useEffect)(() => {
83
73
  const el = timeline_refs_1.timelineVerticalScroll.current;
@@ -106,16 +96,13 @@ const TimelinePinchZoom = () => {
106
96
  if (!videoConfig || videoConfig.durationInFrames < 2) {
107
97
  return;
108
98
  }
109
- if (!canvasContent || canvasContent.type !== 'composition') {
110
- return;
111
- }
112
99
  const scrollEl = timeline_refs_1.scrollableRef.current;
113
100
  if (!scrollEl) {
114
101
  return;
115
102
  }
116
103
  e.preventDefault();
117
104
  suppressWheelFromWebKitPinchRef.current = true;
118
- pinchBaseZoomRef.current = getCurrentTimelineZoom(canvasContent.compositionId);
105
+ pinchBaseZoomRef.current = getCurrentTimelineZoom(videoConfig.id);
119
106
  };
120
107
  const onGestureChange = (event) => {
121
108
  const e = event;
@@ -126,9 +113,6 @@ const TimelinePinchZoom = () => {
126
113
  videoConfig.durationInFrames < 2) {
127
114
  return;
128
115
  }
129
- if (!canvasContent || canvasContent.type !== 'composition') {
130
- return;
131
- }
132
116
  const scrollEl = timeline_refs_1.scrollableRef.current;
133
117
  if (!scrollEl) {
134
118
  return;
@@ -138,7 +122,7 @@ const TimelinePinchZoom = () => {
138
122
  clientX: e.clientX,
139
123
  scrollEl,
140
124
  });
141
- setZoom(canvasContent.compositionId, () => base * e.scale, {
125
+ setZoom(videoConfig.id, () => base * e.scale, {
142
126
  anchorFrame: null,
143
127
  anchorContentX,
144
128
  });
@@ -161,7 +145,6 @@ const TimelinePinchZoom = () => {
161
145
  supportsWebKitPinch,
162
146
  isVideoComposition,
163
147
  videoConfig,
164
- canvasContent,
165
148
  getCurrentTimelineZoom,
166
149
  setZoom,
167
150
  ]);
@@ -180,9 +163,6 @@ const TimelinePinchZoom = () => {
180
163
  videoConfig.durationInFrames < 2) {
181
164
  return;
182
165
  }
183
- if (!canvasContent || canvasContent.type !== 'composition') {
184
- return;
185
- }
186
166
  const [t0, t1] = [event.touches[0], event.touches[1]];
187
167
  const initialDistance = Math.hypot(t1.clientX - t0.clientX, t1.clientY - t0.clientY);
188
168
  if (initialDistance < 1e-6) {
@@ -190,7 +170,7 @@ const TimelinePinchZoom = () => {
190
170
  }
191
171
  touchPinchRef.current = {
192
172
  initialDistance,
193
- initialZoom: getCurrentTimelineZoom(canvasContent.compositionId),
173
+ initialZoom: getCurrentTimelineZoom(videoConfig.id),
194
174
  };
195
175
  };
196
176
  const onTouchMove = (event) => {
@@ -201,9 +181,6 @@ const TimelinePinchZoom = () => {
201
181
  videoConfig.durationInFrames < 2) {
202
182
  return;
203
183
  }
204
- if (!canvasContent || canvasContent.type !== 'composition') {
205
- return;
206
- }
207
184
  const scrollEl = timeline_refs_1.scrollableRef.current;
208
185
  if (!scrollEl) {
209
186
  return;
@@ -217,7 +194,7 @@ const TimelinePinchZoom = () => {
217
194
  clientX,
218
195
  scrollEl,
219
196
  });
220
- setZoom(canvasContent.compositionId, () => pinch.initialZoom * ratio, {
197
+ setZoom(videoConfig.id, () => pinch.initialZoom * ratio, {
221
198
  anchorFrame: null,
222
199
  anchorContentX,
223
200
  });
@@ -241,7 +218,6 @@ const TimelinePinchZoom = () => {
241
218
  editorZoomGestures,
242
219
  isVideoComposition,
243
220
  videoConfig,
244
- canvasContent,
245
221
  getCurrentTimelineZoom,
246
222
  setZoom,
247
223
  ]);
@@ -16,17 +16,11 @@ const TimelinePlayCursorSyncer = () => {
16
16
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
17
17
  const playing = remotion_1.Internals.usePlaying();
18
18
  const { playbackRate } = remotion_1.Internals.usePlaybackRate();
19
- const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
20
19
  const { zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
21
- const compositionId = canvasContent && canvasContent.type === 'composition'
22
- ? canvasContent.compositionId
23
- : null;
24
- // Asset previews have a synthetic video config, but no composition ID
25
- // with which to look up a persisted timeline zoom.
26
20
  const zoom = (0, get_timeline_max_zoom_1.getTimelineZoom)({
27
21
  durationInFrames: (_b = video === null || video === void 0 ? void 0 : video.durationInFrames) !== null && _b !== void 0 ? _b : 1,
28
22
  timelineViewportWidth: (_c = (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _c !== void 0 ? _c : 0,
29
- zoom: compositionId ? ((_d = zoomMap[compositionId]) !== null && _d !== void 0 ? _d : null) : null,
23
+ zoom: video ? ((_d = zoomMap[video.id]) !== null && _d !== void 0 ? _d : null) : null,
30
24
  });
31
25
  if (video) {
32
26
  (0, imperative_state_1.setCurrentFrame)(timelinePosition);