@remotion/studio 4.0.498 → 4.0.500

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 (167) hide show
  1. package/dist/components/AssetSelector.js +8 -6
  2. package/dist/components/AssetSelectorItem.d.ts +24 -0
  3. package/dist/components/AssetSelectorItem.js +144 -83
  4. package/dist/components/Canvas.js +162 -7
  5. package/dist/components/CompositionSelector.js +15 -42
  6. package/dist/components/CompositionSelectorItem.js +21 -13
  7. package/dist/components/ControlButton.js +1 -0
  8. package/dist/components/EditorContent.js +1 -1
  9. package/dist/components/EditorRuler/Ruler.js +5 -3
  10. package/dist/components/ExplorerPanel.js +2 -1
  11. package/dist/components/ExplorerPanelRef.d.ts +2 -0
  12. package/dist/components/ForceSpecificCursor.js +13 -1
  13. package/dist/components/GlobalKeybindings.js +7 -1
  14. package/dist/components/InlineAction.d.ts +2 -1
  15. package/dist/components/InlineAction.js +2 -2
  16. package/dist/components/InlineDropdown.d.ts +1 -1
  17. package/dist/components/InlineDropdown.js +3 -2
  18. package/dist/components/InspectorPanel/AlignmentControls.d.ts +2 -2
  19. package/dist/components/InspectorPanel/AlignmentControls.js +5 -2
  20. package/dist/components/InspectorPanel/CompositionInspector.js +8 -7
  21. package/dist/components/InspectorPanel/CompositionMetadata.js +170 -57
  22. package/dist/components/InspectorPanel/ConnectedCompositionsSection.d.ts +2 -2
  23. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -3
  24. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +7 -7
  25. package/dist/components/InspectorPanel/common.d.ts +17 -4
  26. package/dist/components/InspectorPanel/common.js +60 -6
  27. package/dist/components/InspectorPanel/use-composition-actions.js +1 -0
  28. package/dist/components/InspectorPanel/use-track-for-selection.d.ts +1 -1
  29. package/dist/components/InspectorSequenceSection.js +43 -19
  30. package/dist/components/KeyboardShortcutsExplainer.js +4 -2
  31. package/dist/components/Menu/MenuItem.js +2 -1
  32. package/dist/components/MenuCompositionName.js +30 -7
  33. package/dist/components/MenuToolbar.d.ts +0 -1
  34. package/dist/components/MenuToolbar.js +8 -7
  35. package/dist/components/MobilePanel.d.ts +2 -1
  36. package/dist/components/MobilePanel.js +29 -25
  37. package/dist/components/ModalContainer.d.ts +1 -0
  38. package/dist/components/ModalContainer.js +2 -2
  39. package/dist/components/Modals.js +1 -1
  40. package/dist/components/NewComposition/DismissableModal.d.ts +1 -0
  41. package/dist/components/NewComposition/DismissableModal.js +2 -2
  42. package/dist/components/NewComposition/InputDragger.d.ts +34 -0
  43. package/dist/components/NewComposition/InputDragger.js +262 -23
  44. package/dist/components/OutlineToggle.d.ts +1 -3
  45. package/dist/components/OutlineToggle.js +2 -2
  46. package/dist/components/PreviewToolbar.js +10 -4
  47. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.d.ts +7 -0
  48. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +44 -0
  49. package/dist/components/QuickSwitcher/NoResults.d.ts +1 -1
  50. package/dist/components/QuickSwitcher/NoResults.js +1 -0
  51. package/dist/components/QuickSwitcher/QuickSwitcher.d.ts +5 -0
  52. package/dist/components/QuickSwitcher/QuickSwitcher.js +6 -2
  53. package/dist/components/QuickSwitcher/QuickSwitcherContent.d.ts +5 -0
  54. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +76 -12
  55. package/dist/components/QuickSwitcher/QuickSwitcherResult.d.ts +4 -0
  56. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +11 -8
  57. package/dist/components/QuickSwitcher/asset-search.d.ts +9 -0
  58. package/dist/components/QuickSwitcher/asset-search.js +42 -0
  59. package/dist/components/SelectedOutlineCropControls.d.ts +8 -0
  60. package/dist/components/SelectedOutlineCropControls.js +299 -0
  61. package/dist/components/SelectedOutlineElement.js +83 -43
  62. package/dist/components/SelectedOutlineOverlay.d.ts +2 -2
  63. package/dist/components/SelectedOutlineOverlay.js +130 -8
  64. package/dist/components/SequencePropsSubscriptionProvider.d.ts +2 -0
  65. package/dist/components/SequencePropsSubscriptionProvider.js +31 -3
  66. package/dist/components/SidebarCollapserControls.d.ts +3 -1
  67. package/dist/components/SidebarCollapserControls.js +34 -29
  68. package/dist/components/SnappingToggle.d.ts +1 -3
  69. package/dist/components/SnappingToggle.js +2 -2
  70. package/dist/components/Splitter/SplitterContainer.d.ts +2 -0
  71. package/dist/components/Splitter/SplitterContainer.js +5 -1
  72. package/dist/components/Splitter/SplitterContext.d.ts +2 -0
  73. package/dist/components/Splitter/SplitterContext.js +2 -0
  74. package/dist/components/Splitter/SplitterElement.js +6 -1
  75. package/dist/components/Splitter/SplitterHandle.js +27 -2
  76. package/dist/components/Timeline/Timeline.js +1 -1
  77. package/dist/components/Timeline/TimelineAssetField.d.ts +9 -1
  78. package/dist/components/Timeline/TimelineAssetField.js +52 -100
  79. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +7 -3
  80. package/dist/components/Timeline/TimelineClipboardKeybindings.js +65 -38
  81. package/dist/components/Timeline/TimelineColorField.js +20 -1
  82. package/dist/components/Timeline/TimelineEffectPropItem.js +8 -77
  83. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +1 -0
  84. package/dist/components/Timeline/TimelineHeightContainer.d.ts +2 -2
  85. package/dist/components/Timeline/TimelineInOutDragHandler.js +25 -1
  86. package/dist/components/Timeline/TimelineKeyframeTracksContext.d.ts +3 -3
  87. package/dist/components/Timeline/TimelineLayerEye.js +4 -1
  88. package/dist/components/Timeline/TimelineList.d.ts +2 -2
  89. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +7 -1
  90. package/dist/components/Timeline/TimelineSelection.d.ts +5 -5
  91. package/dist/components/Timeline/TimelineSelection.js +8 -6
  92. package/dist/components/Timeline/TimelineSequence.js +7 -6
  93. package/dist/components/Timeline/TimelineSequenceItem.js +57 -10
  94. package/dist/components/Timeline/TimelineSequenceName.js +1 -0
  95. package/dist/components/Timeline/TimelineSequencePropItem.js +27 -75
  96. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +5 -1
  97. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +29 -12
  98. package/dist/components/Timeline/TimelineTrack.d.ts +2 -2
  99. package/dist/components/Timeline/TimelineTracks.d.ts +2 -2
  100. package/dist/components/Timeline/find-track-for-node-path-info.d.ts +1 -1
  101. package/dist/components/Timeline/get-sequence-context-menu-items.js +14 -12
  102. package/dist/components/Timeline/reset-selected-timeline-props.js +18 -10
  103. package/dist/components/Timeline/save-effect-prop.d.ts +10 -0
  104. package/dist/components/Timeline/save-effect-prop.js +52 -1
  105. package/dist/components/Timeline/should-show-track-in-timeline.d.ts +2 -2
  106. package/dist/components/Timeline/timeline-asset-link.js +17 -1
  107. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +4 -0
  108. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +9 -3
  109. package/dist/components/Timeline/use-timeline-height.d.ts +2 -2
  110. package/dist/components/Timeline/use-timeline-keyframe-drag.js +6 -4
  111. package/dist/components/TopPanel.js +3 -2
  112. package/dist/components/UndoRedoButtons.js +27 -5
  113. package/dist/components/composition-drop-preview.d.ts +33 -0
  114. package/dist/components/composition-drop-preview.js +68 -0
  115. package/dist/components/drop-handler-data.d.ts +1 -1
  116. package/dist/components/drop-handler-data.js +27 -60
  117. package/dist/components/effect-drag-and-drop.d.ts +1 -1
  118. package/dist/components/effect-drag-and-drop.js +7 -55
  119. package/dist/components/element-drag-and-drop.d.ts +1 -1
  120. package/dist/components/element-drag-and-drop.js +5 -17
  121. package/dist/components/handle-drop.js +0 -1
  122. package/dist/components/import-assets.d.ts +7 -8
  123. package/dist/components/import-assets.js +2 -9
  124. package/dist/components/menu-toolbar-height.d.ts +1 -0
  125. package/dist/components/menu-toolbar-height.js +4 -0
  126. package/dist/components/selected-outline-drag.d.ts +41 -4
  127. package/dist/components/selected-outline-drag.js +179 -2
  128. package/dist/components/selected-outline-geometry.d.ts +1 -0
  129. package/dist/components/selected-outline-measurement.d.ts +11 -0
  130. package/dist/components/selected-outline-measurement.js +64 -3
  131. package/dist/components/selected-outline-types.d.ts +44 -1
  132. package/dist/components/selected-outline-types.js +21 -1
  133. package/dist/error-overlay/remotion-overlay/Overlay.js +3 -3
  134. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +2 -3
  135. package/dist/esm/{chunk-7a6q9hk2.js → chunk-dr1y1vm3.js} +11851 -9494
  136. package/dist/esm/internals.mjs +11851 -9494
  137. package/dist/esm/previewEntry.mjs +55150 -52795
  138. package/dist/esm/renderEntry.mjs +1 -1
  139. package/dist/helpers/calculate-timeline.d.ts +2 -2
  140. package/dist/helpers/calculate-timeline.js +8 -28
  141. package/dist/helpers/get-effective-translation.d.ts +13 -1
  142. package/dist/helpers/get-effective-translation.js +12 -6
  143. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +3 -10
  144. package/dist/helpers/get-timeline-sequence-sort-key.js +5 -13
  145. package/dist/helpers/interactivity-enabled.d.ts +1 -0
  146. package/dist/helpers/interactivity-enabled.js +7 -2
  147. package/dist/helpers/is-mac.d.ts +1 -0
  148. package/dist/helpers/is-mac.js +4 -0
  149. package/dist/helpers/open-in-editor.d.ts +5 -1
  150. package/dist/helpers/open-in-editor.js +15 -1
  151. package/dist/helpers/ruler-canvas-size.d.ts +7 -0
  152. package/dist/helpers/ruler-canvas-size.js +14 -1
  153. package/dist/helpers/sort-by-nonce-history.js +97 -19
  154. package/dist/helpers/use-image-metadata.d.ts +1 -0
  155. package/dist/helpers/use-image-metadata.js +8 -5
  156. package/dist/helpers/use-keybinding.js +2 -3
  157. package/dist/helpers/use-media-metadata.d.ts +1 -0
  158. package/dist/helpers/use-media-metadata.js +8 -5
  159. package/dist/helpers/use-menu-structure.js +10 -1
  160. package/dist/icons/caret.d.ts +1 -0
  161. package/dist/icons/caret.js +2 -2
  162. package/dist/icons/pen.d.ts +5 -0
  163. package/dist/icons/pen.js +8 -0
  164. package/dist/state/modals.d.ts +5 -0
  165. package/package.json +13 -12
  166. package/dist/helpers/get-timeline-sequence-hash.d.ts +0 -6
  167. package/dist/helpers/get-timeline-sequence-hash.js +0 -33
@@ -285,18 +285,8 @@ const getEasingClipboardDataFromSelection = ({ selection, sequences, overrideIds
285
285
  };
286
286
  };
287
287
  exports.getEasingClipboardDataFromSelection = getEasingClipboardDataFromSelection;
288
- const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
288
+ const getPasteEffectPropTargetForSelection = ({ selection, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
289
289
  var _a;
290
- if (selectedItems.length === 0) {
291
- return { type: 'none' };
292
- }
293
- if (selectedItems.length !== 1) {
294
- return { type: 'multiple' };
295
- }
296
- const [selection] = selectedItems;
297
- if (!selection) {
298
- return { type: 'none' };
299
- }
300
290
  if (selection.type !== 'sequence-effect-prop' &&
301
291
  selection.type !== 'sequence-effect') {
302
292
  return { type: 'none' };
@@ -348,12 +338,42 @@ const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequen
348
338
  }
349
339
  return {
350
340
  type: 'valid',
351
- fileName: selection.nodePathInfo.sequenceSubscriptionKey.absolutePath,
352
- nodePath: selection.nodePathInfo.sequenceSubscriptionKey,
353
- effectIndex: target.effectIndex,
354
- fieldKey: target.fieldKey,
355
- defaultValue: getDefaultValue(fieldSchema),
356
- schema: effect.schema,
341
+ target: {
342
+ fileName: selection.nodePathInfo.sequenceSubscriptionKey.absolutePath,
343
+ nodePath: selection.nodePathInfo.sequenceSubscriptionKey,
344
+ effectIndex: target.effectIndex,
345
+ fieldKey: target.fieldKey,
346
+ defaultValue: getDefaultValue(fieldSchema),
347
+ schema: effect.schema,
348
+ },
349
+ };
350
+ };
351
+ const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
352
+ if (selectedItems.length === 0) {
353
+ return { type: 'none' };
354
+ }
355
+ const targets = [];
356
+ for (const selection of selectedItems) {
357
+ const result = getPasteEffectPropTargetForSelection({
358
+ selection,
359
+ payload,
360
+ propStatuses,
361
+ sequences,
362
+ overrideIdsToNodePaths,
363
+ });
364
+ if (result.type !== 'valid') {
365
+ return result;
366
+ }
367
+ targets.push(result.target);
368
+ }
369
+ return {
370
+ type: 'valid',
371
+ targets: [
372
+ ...new Map(targets.map((target) => [
373
+ `${makeTargetKey(target.nodePath)}:${target.effectIndex}:${target.fieldKey}`,
374
+ target,
375
+ ])).values(),
376
+ ],
357
377
  };
358
378
  };
359
379
  exports.getPasteEffectPropTarget = getPasteEffectPropTarget;
@@ -730,11 +750,8 @@ const TimelineClipboardKeybindings = () => {
730
750
  });
731
751
  if (effectPropTarget.type !== 'valid') {
732
752
  switch (effectPropTarget.type) {
733
- case 'multiple':
734
- (0, NotificationCenter_1.showNotification)('Select one target effect prop or effect to paste onto', 3000);
735
- return;
736
753
  case 'none':
737
- (0, NotificationCenter_1.showNotification)('Select a matching effect prop or effect to paste onto', 3000);
754
+ (0, NotificationCenter_1.showNotification)('Select matching effect props or effects to paste onto', 3000);
738
755
  return;
739
756
  case 'unsupported':
740
757
  (0, NotificationCenter_1.showNotification)('This sequence does not support effects', 3000);
@@ -752,26 +769,36 @@ const TimelineClipboardKeybindings = () => {
752
769
  throw new Error(`Unexpected paste target: ${effectPropTarget}`);
753
770
  }
754
771
  }
755
- return (0, save_effect_prop_1.saveEffectProp)({
756
- fileName: effectPropTarget.fileName,
757
- nodePath: effectPropTarget.nodePath,
758
- effectIndex: effectPropTarget.effectIndex,
759
- fieldKey: effectPropTarget.fieldKey,
760
- ...(effectPropResult.data.param.type === 'static'
761
- ? {
762
- type: 'value',
763
- value: effectPropResult.data.param.value,
764
- }
765
- : {
766
- type: 'effect-param',
767
- effectParam: effectPropResult.data.param,
768
- }),
769
- defaultValue: effectPropTarget.defaultValue,
770
- schema: effectPropTarget.schema,
772
+ return (0, save_effect_prop_1.saveMultipleEffectProps)({
773
+ changes: effectPropTarget.targets.map((pasteTarget) => ({
774
+ fileName: pasteTarget.fileName,
775
+ nodePath: pasteTarget.nodePath,
776
+ effectIndex: pasteTarget.effectIndex,
777
+ fieldKey: pasteTarget.fieldKey,
778
+ ...(effectPropResult.data.param.type === 'static'
779
+ ? {
780
+ type: 'value',
781
+ value: effectPropResult.data.param.value,
782
+ }
783
+ : {
784
+ type: 'effect-param',
785
+ effectParam: effectPropResult.data.param,
786
+ }),
787
+ defaultValue: pasteTarget.defaultValue,
788
+ schema: pasteTarget.schema,
789
+ })),
771
790
  setPropStatuses,
772
791
  clientId,
792
+ undoLabel: effectPropTarget.targets.length > 1
793
+ ? 'Paste effect prop onto selected effects'
794
+ : 'Paste effect prop',
795
+ redoLabel: effectPropTarget.targets.length > 1
796
+ ? 'Reapply effect prop paste onto selected effects'
797
+ : 'Reapply effect prop paste',
773
798
  }).then(() => {
774
- (0, NotificationCenter_1.showNotification)('Pasted effect prop', 2000);
799
+ (0, NotificationCenter_1.showNotification)(effectPropTarget.targets.length > 1
800
+ ? 'Pasted effect prop onto selected effects'
801
+ : 'Pasted effect prop', 2000);
775
802
  });
776
803
  }
777
804
  const result = envelope === null
@@ -12,8 +12,22 @@ const containerStyle = {
12
12
  };
13
13
  const SWATCH_WIDTH = 20;
14
14
  const SWATCH_HEIGHT = 15;
15
+ const DEFAULT_SET_COLOR = '#808080';
16
+ const noneLabelStyle = {
17
+ color: colors_1.LIGHT_TEXT,
18
+ fontSize: 12,
19
+ };
20
+ const setButtonStyle = {
21
+ background: 'none',
22
+ border: 'none',
23
+ color: colors_1.BLUE,
24
+ cursor: 'pointer',
25
+ fontSize: 12,
26
+ margin: 0,
27
+ padding: 0,
28
+ };
15
29
  const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragValueChange, onDragEnd, }) => {
16
- var _a;
30
+ var _a, _b;
17
31
  const currentValue = typeof effectiveValue === 'string'
18
32
  ? effectiveValue
19
33
  : field.fieldSchema.type === 'color'
@@ -33,6 +47,11 @@ const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragV
33
47
  marginLeft: 5,
34
48
  };
35
49
  }, []);
50
+ if (currentValue === 'none') {
51
+ return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
52
+ jsx_runtime_1.jsx("span", { style: noneLabelStyle, children: "None" }), jsx_runtime_1.jsx("button", { type: "button", style: setButtonStyle, title: `Set ${(_b = field.description) !== null && _b !== void 0 ? _b : field.key} to gray`, onClick: () => onChangeComplete(DEFAULT_SET_COLOR), children: "Set" })
53
+ ] }));
54
+ }
36
55
  return (jsx_runtime_1.jsx("span", { style: containerStyle, children: jsx_runtime_1.jsx(ColorPicker_1.ColorPicker, { value: currentValue, status: "ok", onChange: onChange, onChangeComplete: onChangeComplete, width: SWATCH_WIDTH, height: SWATCH_HEIGHT, disabled: false, name: field.key, title: currentValue, style: swatchStyle }) }));
37
56
  };
38
57
  exports.TimelineColorField = TimelineColorField;
@@ -6,10 +6,10 @@ const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const client_id_1 = require("../../helpers/client-id");
9
+ const open_in_editor_1 = require("../../helpers/open-in-editor");
9
10
  const call_api_1 = require("../call-api");
10
11
  const ContextMenu_1 = require("../ContextMenu");
11
12
  const call_add_keyframe_1 = require("./call-add-keyframe");
12
- const get_animation_item_selection_for_frame_1 = require("./get-animation-item-selection-for-frame");
13
13
  const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
14
14
  const save_effect_prop_1 = require("./save-effect-prop");
15
15
  const save_prop_queue_1 = require("./save-prop-queue");
@@ -21,7 +21,6 @@ const TimelineLayerEye_1 = require("./TimelineLayerEye");
21
21
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
22
22
  const TimelineSchemaField_1 = require("./TimelineSchemaField");
23
23
  const TimelineSelection_1 = require("./TimelineSelection");
24
- const update_selected_easing_1 = require("./update-selected-easing");
25
24
  const fieldRowBase = {};
26
25
  const isKeyframedStatus = (status) => {
27
26
  return status.status === 'keyframed';
@@ -218,9 +217,6 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
218
217
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
219
218
  const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
220
219
  const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
221
- const { selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
222
- const setFrame = remotion_1.Internals.useTimelineSetFrame();
223
- const videoConfig = (0, remotion_1.useVideoConfig)();
224
220
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
225
221
  const sourceFrame = timelinePosition - keyframeDisplayOffset;
226
222
  const style = (0, react_1.useMemo)(() => {
@@ -314,82 +310,17 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
314
310
  },
315
311
  ];
316
312
  }, [canShowReset, onReset]);
317
- const seekToDisplayFrame = (0, react_1.useCallback)((frame) => {
318
- setFrame((current) => {
319
- const next = { ...current, [videoConfig.id]: frame };
320
- remotion_1.Internals.persistCurrentFrame(next);
321
- return next;
322
- });
323
- }, [setFrame, videoConfig.id]);
324
313
  const onPropertyDoubleClick = (0, react_1.useCallback)((event) => {
325
- if (propStatus === null || propStatus.status === 'computed') {
326
- return;
327
- }
328
- const keyframeSelection = {
329
- type: 'keyframe',
330
- nodePathInfo,
331
- frame: sourceFrame + keyframeDisplayOffset,
332
- };
333
- if (propStatus.status === 'static') {
334
- if (!keyframable || previewServerState.type !== 'connected') {
335
- return;
336
- }
337
- const value = remotion_1.Internals.getEffectiveVisualModeValue({
338
- propStatus,
339
- dragOverrideValue,
340
- frame: sourceFrame,
341
- defaultValue: field.fieldSchema.default,
342
- shouldResortToDefaultValueIfUndefined: true,
343
- });
344
- event.stopPropagation();
345
- (0, call_add_keyframe_1.callAddEffectKeyframe)({
346
- fileName: validatedLocation.source,
347
- nodePath,
348
- effectIndex: field.effectIndex,
349
- fieldKey: field.key,
350
- sourceFrame,
351
- value,
352
- schema: field.effectSchema,
353
- setPropStatuses,
354
- clientId: previewServerState.clientId,
355
- }).catch(() => undefined);
356
- selectItems([keyframeSelection], { reveal: true });
357
- seekToDisplayFrame(keyframeSelection.frame);
358
- return;
359
- }
360
- const targetSelection = (0, get_animation_item_selection_for_frame_1.getAnimationItemSelectionForSourceFrame)({
361
- includeEasings: (0, update_selected_easing_1.canEditEasingForInterpolationFunction)(propStatus.interpolationFunction),
362
- keyframeDisplayOffset,
363
- keyframes: propStatus.keyframes,
364
- nodePathInfo,
365
- sourceFrame,
366
- });
367
- if (targetSelection === null) {
314
+ if (!window.remotion_editorName ||
315
+ previewServerState.type !== 'connected') {
368
316
  return;
369
317
  }
370
318
  event.stopPropagation();
371
- selectItems([targetSelection], { reveal: true });
372
- if (targetSelection.type === 'keyframe') {
373
- seekToDisplayFrame(targetSelection.frame);
374
- }
375
- }, [
376
- dragOverrideValue,
377
- field.effectIndex,
378
- field.effectSchema,
379
- field.fieldSchema.default,
380
- field.key,
381
- keyframeDisplayOffset,
382
- keyframable,
383
- nodePath,
384
- nodePathInfo,
385
- previewServerState,
386
- propStatus,
387
- seekToDisplayFrame,
388
- selectItems,
389
- setPropStatuses,
390
- sourceFrame,
391
- validatedLocation.source,
392
- ]);
319
+ (0, open_in_editor_1.openOriginalPositionInEditorAtProperty)({
320
+ originalPosition: validatedLocation,
321
+ property: field.key,
322
+ }).catch(() => undefined);
323
+ }, [field.key, previewServerState.type, validatedLocation]);
393
324
  const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, children: jsx_runtime_1.jsx(exports.TimelineEffectPropValue, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, sourceFrame: sourceFrame }) }) }));
394
325
  return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: row }));
395
326
  };
@@ -43,6 +43,7 @@ const TimelineKeyframeEasingLine_1 = require("./TimelineKeyframeEasingLine");
43
43
  const TimelineSelection_1 = require("./TimelineSelection");
44
44
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
45
45
  const row = {
46
+ overflow: 'hidden',
46
47
  position: 'relative',
47
48
  };
48
49
  const rowSeparator = {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import type { TrackWithHash } from '../../helpers/get-timeline-sequence-sort-key';
2
+ import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
3
  export declare const TimelineHeightContainer: React.NamedExoticComponent<{
4
- readonly shown: TrackWithHash[];
4
+ readonly shown: TimelineTrackData[];
5
5
  readonly hasBeenCut: boolean;
6
6
  readonly children: React.ReactNode;
7
7
  }>;
@@ -252,17 +252,41 @@ const TimelineInOutDragHandlerInner = () => {
252
252
  videoConfig,
253
253
  width,
254
254
  ]);
255
+ const onPointerCancelInOut = (0, react_1.useCallback)(() => {
256
+ document.body.style.userSelect = '';
257
+ document.body.style.webkitUserSelect = '';
258
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
259
+ setInOutDragging({
260
+ dragging: false,
261
+ });
262
+ }, []);
255
263
  (0, react_1.useEffect)(() => {
256
264
  if (inOutDragging.dragging === false) {
257
265
  return;
258
266
  }
259
267
  window.addEventListener('pointermove', onPointerMoveInOut);
260
268
  window.addEventListener('pointerup', onPointerUpInOut);
269
+ window.addEventListener('pointercancel', onPointerCancelInOut);
270
+ window.addEventListener('blur', onPointerCancelInOut);
261
271
  return () => {
262
272
  window.removeEventListener('pointermove', onPointerMoveInOut);
263
273
  window.removeEventListener('pointerup', onPointerUpInOut);
274
+ window.removeEventListener('pointercancel', onPointerCancelInOut);
275
+ window.removeEventListener('blur', onPointerCancelInOut);
276
+ };
277
+ }, [
278
+ inOutDragging.dragging,
279
+ onPointerCancelInOut,
280
+ onPointerMoveInOut,
281
+ onPointerUpInOut,
282
+ ]);
283
+ (0, react_1.useEffect)(() => {
284
+ return () => {
285
+ document.body.style.userSelect = '';
286
+ document.body.style.webkitUserSelect = '';
287
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
264
288
  };
265
- }, [inOutDragging.dragging, onPointerMoveInOut, onPointerUpInOut]);
289
+ }, []);
266
290
  const inContextMenu = (0, react_1.useMemo)(() => {
267
291
  return [
268
292
  {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import type { TrackWithHash } from '../../helpers/get-timeline-sequence-sort-key';
2
+ import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
3
  export declare const TimelineKeyframeTracksProvider: React.FC<{
4
- readonly tracks: readonly TrackWithHash[];
4
+ readonly tracks: readonly TimelineTrackData[];
5
5
  readonly children: React.ReactNode;
6
6
  }>;
7
- export declare const useTimelineKeyframeTracks: () => readonly TrackWithHash[];
7
+ export declare const useTimelineKeyframeTracks: () => readonly TimelineTrackData[];
@@ -64,7 +64,10 @@ const TimelineLayerEye = ({ onInvoked, hidden, type }) => {
64
64
  onInvoked(layerPointedDown);
65
65
  }
66
66
  }, [onInvoked]);
67
- return (jsx_runtime_1.jsx("div", { style: exports.timelineLayerIconContainer, draggable: false, onDragStart: onDragStart, onPointerEnter: onPointerEnter, onPointerDown: onPointerDown, children: renderAction(colors_1.LIGHT_COLOR) }));
67
+ const onDoubleClick = (0, react_1.useCallback)((e) => {
68
+ e.stopPropagation();
69
+ }, []);
70
+ return (jsx_runtime_1.jsx("div", { style: exports.timelineLayerIconContainer, draggable: false, onDragStart: onDragStart, onDoubleClick: onDoubleClick, onPointerEnter: onPointerEnter, onPointerDown: onPointerDown, children: renderAction(colors_1.LIGHT_COLOR) }));
68
71
  };
69
72
  exports.TimelineLayerEye = TimelineLayerEye;
70
73
  const spacerStyle = {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { TrackWithHash } from '../../helpers/get-timeline-sequence-sort-key';
2
+ import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
3
  export declare const TimelineList: React.FC<{
4
- readonly timeline: TrackWithHash[];
4
+ readonly timeline: TimelineTrackData[];
5
5
  }>;
@@ -17,6 +17,12 @@ const TimelineUvCoordinateField_1 = require("./TimelineUvCoordinateField");
17
17
  const inlineWrapper = {
18
18
  fontSize: 12,
19
19
  };
20
+ const assetInlineWrapper = {
21
+ ...inlineWrapper,
22
+ display: 'flex',
23
+ flex: 1,
24
+ minWidth: 0,
25
+ };
20
26
  const isTimelinePrimitiveFieldInfo = (field) => {
21
27
  return field.typeName !== 'array' && field.fieldSchema.type !== 'array';
22
28
  };
@@ -60,7 +66,7 @@ const TimelinePrimitiveFieldValue = ({ field, onSave, onDragValueChange, onDragE
60
66
  return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineFontFamilyField_1.TimelineFontFamilyField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
61
67
  }
62
68
  if (field.typeName === 'asset') {
63
- return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineAssetField_1.TimelineAssetField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
69
+ return (jsx_runtime_1.jsx("span", { style: assetInlineWrapper, children: jsx_runtime_1.jsx(TimelineAssetField_1.TimelineAssetField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
64
70
  }
65
71
  throw new Error(`Unsupported field type: ${field.typeName}`);
66
72
  };
@@ -1,6 +1,6 @@
1
1
  import React, { type CSSProperties } from 'react';
2
2
  import { type GetDragOverrides, type GetEffectDragOverrides, type PropStatuses } from 'remotion';
3
- import type { SequenceNodePathInfo, TrackWithHash } from '../../helpers/get-timeline-sequence-sort-key';
3
+ import type { SequenceNodePathInfo, TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
4
4
  import { type GetIsExpanded } from '../ExpandedTracksProvider';
5
5
  export declare const TIMELINE_SELECTED_BACKGROUND = "#3B3F42";
6
6
  export declare const TIMELINE_SELECTED_LABEL_BACKGROUND = "#B0B0B0";
@@ -145,23 +145,23 @@ type TimelineSelectionOptions = {
145
145
  };
146
146
  export declare const getTimelineSelectionFromNodePathInfo: (nodePathInfo: SequenceNodePathInfo | null) => TimelineSelection | null;
147
147
  export declare const getTimelineSelectionKey: (item: TimelineSelection) => string;
148
- export declare const getSelectableTimelineSequenceSelections: (tracks: readonly Pick<TrackWithHash, "nodePathInfo">[]) => TimelineSelection[];
148
+ export declare const getSelectableTimelineSequenceSelections: (tracks: readonly Pick<TimelineTrackData, "nodePathInfo">[]) => TimelineSelection[];
149
149
  export declare const getSelectableTimelineItems: ({ getDragOverrides, getEffectDragOverrides, getIsExpanded, propStatuses, selectedItems, timeline, timelinePosition, }: {
150
150
  readonly getDragOverrides: GetDragOverrides;
151
151
  readonly getEffectDragOverrides: GetEffectDragOverrides;
152
152
  readonly getIsExpanded: GetIsExpanded;
153
153
  readonly propStatuses: PropStatuses;
154
154
  readonly selectedItems: readonly TimelineSelection[];
155
- readonly timeline: readonly TrackWithHash[];
155
+ readonly timeline: readonly TimelineTrackData[];
156
156
  readonly timelinePosition: number;
157
157
  }) => TimelineSelection[];
158
158
  export declare const getTimelineSequenceSelectionKey: (nodePathInfo: SequenceNodePathInfo) => string;
159
159
  export declare const TimelineSelectAllKeybindings: React.FC<{
160
- readonly timeline: readonly TrackWithHash[];
160
+ readonly timeline: readonly TimelineTrackData[];
161
161
  }>;
162
162
  export declare const TimelineSelectableItemsProvider: React.FC<{
163
163
  readonly children: React.ReactNode;
164
- readonly timeline: readonly TrackWithHash[];
164
+ readonly timeline: readonly TimelineTrackData[];
165
165
  }>;
166
166
  export declare const TimelineSelectionProvider: React.FC<{
167
167
  readonly children: React.ReactNode;
@@ -595,9 +595,9 @@ const TimelineSelectionProvider = ({ children }) => {
595
595
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
596
596
  const timelineSelectionScope = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
597
597
  const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
598
- const canSelect = (0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
599
- previewServerState.type === 'connected' &&
600
- !window.remotion_isReadOnlyStudio;
598
+ const canSelect = (0, interactivity_enabled_1.isStudioSelectionEnabled)() &&
599
+ (previewServerState.type === 'connected' ||
600
+ window.remotion_isReadOnlyStudio);
601
601
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
602
602
  const selectionAnchor = (0, react_1.useRef)(null);
603
603
  const selectionScope = (0, react_1.useRef)(null);
@@ -614,7 +614,8 @@ const TimelineSelectionProvider = ({ children }) => {
614
614
  setSelectedItems([]);
615
615
  }
616
616
  }, [canSelect]);
617
- const canSelectItem = (0, react_1.useCallback)((_item) => canSelect, [canSelect]);
617
+ const canSelectItem = (0, react_1.useCallback)((item) => canSelect &&
618
+ (!window.remotion_isReadOnlyStudio || item.type === 'sequence'), [canSelect]);
618
619
  const getCurrentAvailableSelectionState = (0, react_1.useCallback)((currentSelectedItems) => {
619
620
  if (selectionScope.current !== timelineSelectionScope) {
620
621
  return exports.EMPTY_TIMELINE_SELECTION_STATE;
@@ -867,8 +868,9 @@ const TimelineSelectionProvider = ({ children }) => {
867
868
  ]);
868
869
  const currentSelection = (0, react_1.useRef)(value);
869
870
  currentSelection.current = value;
870
- return (jsx_runtime_1.jsx(CurrentTimelineSelectionContext.Provider, { value: currentSelection, children: jsx_runtime_1.jsxs(TimelineSelectionContext.Provider, { value: value, children: [children, jsx_runtime_1.jsx(TimelineEscapeKeybindings, {}), jsx_runtime_1.jsx(TimelineClipboardKeybindings_1.TimelineClipboardKeybindings, {}), jsx_runtime_1.jsx(TimelineDeleteKeybindings_1.TimelineDeleteKeybindings, {})
871
- ] }) }));
871
+ return (jsx_runtime_1.jsx(CurrentTimelineSelectionContext.Provider, { value: currentSelection, children: jsx_runtime_1.jsxs(TimelineSelectionContext.Provider, { value: value, children: [children, jsx_runtime_1.jsx(TimelineEscapeKeybindings, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
872
+ jsx_runtime_1.jsx(TimelineClipboardKeybindings_1.TimelineClipboardKeybindings, {}), jsx_runtime_1.jsx(TimelineDeleteKeybindings_1.TimelineDeleteKeybindings, {})
873
+ ] })) : null] }) }));
872
874
  };
873
875
  exports.TimelineSelectionProvider = TimelineSelectionProvider;
874
876
  const useTimelineSelection = () => {
@@ -185,6 +185,11 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
185
185
  }, [propStatuses, nodePath]);
186
186
  const durationCanUpdate = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
187
187
  ((_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames) === null || _a === void 0 ? void 0 : _a.status) === 'static');
188
+ const durationCanResize = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
189
+ (0, TimelineSequenceRightEdgeDragHandle_1.canResizeTimelineSequenceDuration)({
190
+ sequence: s,
191
+ status: propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames,
192
+ }));
188
193
  const fromCanUpdate = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
189
194
  ((_b = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.from) === null || _b === void 0 ? void 0 : _b.status) === 'static');
190
195
  const trimBeforeCanUpdate = Boolean((0, interactivity_enabled_1.isStudioInteractivityEnabled)() &&
@@ -336,9 +341,6 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
336
341
  validatedSource: (_f = validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) !== null && _f !== void 0 ? _f : null,
337
342
  });
338
343
  const contextMenuValues = (0, react_1.useMemo)(() => {
339
- if (!previewConnected) {
340
- return [];
341
- }
342
344
  return (0, get_sequence_context_menu_items_1.getSequenceContextMenuItems)({
343
345
  assetLinkInfo,
344
346
  canOpenInEditor,
@@ -371,7 +373,6 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
371
373
  onDuplicateSequenceFromSource,
372
374
  openInEditor,
373
375
  originalLocation,
374
- previewConnected,
375
376
  s,
376
377
  selectAsset,
377
378
  ]);
@@ -446,7 +447,7 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
446
447
  const showRightEdgeDragHandle = (0, TimelineSequenceRightEdgeDragHandle_1.isTimelineSequenceDurationDraggable)(s) &&
447
448
  nodePath !== null &&
448
449
  validatedLocation !== null &&
449
- durationCanUpdate;
450
+ durationCanResize;
450
451
  const showLeftEdgeDragHandle = (0, TimelineSequenceRightEdgeDragHandle_1.isTimelineSequenceLeftEdgeDraggable)(s) &&
451
452
  nodePath !== null &&
452
453
  validatedLocation !== null &&
@@ -457,6 +458,6 @@ const TimelineSequenceInner = ({ s, connectedCompositions, windowWidth, nodePath
457
458
  return null;
458
459
  }
459
460
  const sequence = (jsx_runtime_1.jsxs(TimelineSequenceCurrentFrame, { s: s, displayDurationInFrames: displayDurationInFrames, premountWidth: premountWidth, postmountWidth: postmountWidth, style: style, nodePathInfo: nodePathInfo, sequenceFrameOffset: sequenceFrameOffset, fromCanUpdate: fromCanUpdate, frozenFrame: frozenFrame, onMoveDragPointerDown: onMoveDragPointerDown, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, children: [s.type === 'audio' ? (jsx_runtime_1.jsx("div", { style: mediaVisualizationStyle, children: jsx_runtime_1.jsx(AudioWaveform_1.AudioWaveform, { src: s.src, height: timeline_layout_1.TIMELINE_LAYER_HEIGHT_AUDIO, doesVolumeChange: s.doesVolumeChange, visualizationWidth: mediaVisualizationLayout.width, startFrom: s.startMediaFrom, durationInFrames: s.duration, volume: s.volume, playbackRate: s.playbackRate, loopDisplay: s.loopDisplay }) })) : null, s.type === 'video' ? (jsx_runtime_1.jsx(TimelineVideoInfo_1.TimelineVideoInfo, { src: s.src, visualizationWidth: width, naturalWidth: naturalWidth, startMediaFrom: s.startMediaFrom, mediaFrameAtSequenceZero: s.mediaFrameAtSequenceZero, sequenceFrameOffset: sequenceFrameOffset, durationInFrames: s.duration, playbackRate: s.playbackRate, volume: s.volume, doesVolumeChange: s.doesVolumeChange, premountWidth: premountWidth !== null && premountWidth !== void 0 ? premountWidth : 0, postmountWidth: postmountWidth !== null && postmountWidth !== void 0 ? postmountWidth : 0, loopDisplay: s.loopDisplay, frozenMediaFrame: s.frozenMediaFrame, extendLastFrame: extendVideoLastFrame })) : null, s.type === 'image' ? (jsx_runtime_1.jsx("div", { style: mediaVisualizationStyle, children: jsx_runtime_1.jsx(TimelineImageInfo_1.TimelineImageInfo, { src: s.src, visualizationWidth: mediaVisualizationLayout.width }) })) : null, s.loopDisplay === undefined ? null : (jsx_runtime_1.jsx(LoopedTimelineIndicators_1.LoopedTimelineIndicator, { loops: s.loopDisplay.numberOfTimes })), showLeftEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceLeftEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_h = video.durationInFrames) !== null && _h !== void 0 ? _h : 1 })) : null, showRightEdgeDragHandle && nodePathInfo && validatedLocation ? (jsx_runtime_1.jsx(TimelineSequenceRightEdgeDragHandle_1.TimelineSequenceRightEdgeDragHandle, { nodePathInfo: nodePathInfo, windowWidth: windowWidth, timelineDurationInFrames: (_j = video.durationInFrames) !== null && _j !== void 0 ? _j : 1 })) : null] }));
460
- return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: onContextMenuOpen, children: sequence })) : (sequence);
461
+ return previewConnected || window.remotion_isReadOnlyStudio ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: onContextMenuOpen, children: sequence })) : (sequence);
461
462
  };
462
463
  exports.TimelineSequence = react_1.default.memo(TimelineSequenceFn);