@remotion/studio 4.0.519 → 4.0.521

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 (130) hide show
  1. package/dist/api/shut-down-studio.d.ts +6 -0
  2. package/dist/api/shut-down-studio.js +23 -0
  3. package/dist/api/visual-control.js +2 -2
  4. package/dist/components/AudioWaveform.js +16 -7
  5. package/dist/components/Canvas.js +114 -48
  6. package/dist/components/CaptionInspector.d.ts +1 -0
  7. package/dist/components/CaptionInspector.js +43 -2
  8. package/dist/components/CaptionTextEditor.js +1 -1
  9. package/dist/components/CompositionSelector.js +41 -34
  10. package/dist/components/CompositionSelectorItem.d.ts +7 -0
  11. package/dist/components/CompositionSelectorItem.js +344 -73
  12. package/dist/components/CurrentCompositionSideEffects.js +5 -0
  13. package/dist/components/ElementInstallConfirmation.d.ts +2 -23
  14. package/dist/components/ElementInstallConfirmation.js +89 -65
  15. package/dist/components/ElementLibraryModal.js +3 -1
  16. package/dist/components/FpsCounter.js +1 -1
  17. package/dist/components/FramePersistor.js +1 -1
  18. package/dist/components/InlineCaptionInspector.js +37 -1
  19. package/dist/components/InspectorPanel/ElementLibraryButton.js +3 -18
  20. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -3
  21. package/dist/components/InspectorPanel/use-composition-actions.js +5 -8
  22. package/dist/components/InspectorSequenceSection.js +1 -4
  23. package/dist/components/Menu/MenuSubItem.js +1 -1
  24. package/dist/components/ModalContainer.d.ts +1 -0
  25. package/dist/components/ModalContainer.js +2 -2
  26. package/dist/components/ModalHeader.js +5 -1
  27. package/dist/components/Modals.js +1 -1
  28. package/dist/components/NewComposition/NewComposition.js +2 -2
  29. package/dist/components/PlayPause.js +2 -13
  30. package/dist/components/PreviewToolbar.js +1 -1
  31. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +29 -15
  32. package/dist/components/QuickSwitcher/QuickSwitcherResult.d.ts +14 -1
  33. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +64 -9
  34. package/dist/components/QuickSwitcher/asset-search.d.ts +0 -1
  35. package/dist/components/QuickSwitcher/asset-search.js +1 -16
  36. package/dist/components/QuickSwitcher/composition-search.d.ts +16 -0
  37. package/dist/components/QuickSwitcher/composition-search.js +136 -0
  38. package/dist/components/RenderButton.js +2 -2
  39. package/dist/components/RenderModal/RenderStatusModal.js +7 -1
  40. package/dist/components/RenderModal/ServerRenderModal.js +1 -1
  41. package/dist/components/RenderModal/WebRenderModal.js +1 -1
  42. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -1
  43. package/dist/components/ResetZoomButton.js +17 -2
  44. package/dist/components/SelectedOutlineElement.js +10 -30
  45. package/dist/components/SettingsModal.js +8 -5
  46. package/dist/components/TimeValue.js +36 -7
  47. package/dist/components/Timeline/Timeline.d.ts +1 -1
  48. package/dist/components/Timeline/Timeline.js +33 -20
  49. package/dist/components/Timeline/TimelineAssetField.d.ts +0 -1
  50. package/dist/components/Timeline/TimelineAssetField.js +17 -9
  51. package/dist/components/Timeline/TimelineCollapseToggle.js +1 -1
  52. package/dist/components/Timeline/TimelineDeleteKeybindings.js +5 -90
  53. package/dist/components/Timeline/TimelineDragHandler.js +18 -8
  54. package/dist/components/Timeline/TimelineFontWeightField.d.ts +11 -0
  55. package/dist/components/Timeline/TimelineFontWeightField.js +65 -0
  56. package/dist/components/Timeline/TimelineInOutDragHandler.js +2 -3
  57. package/dist/components/Timeline/TimelineLayerChildren.d.ts +21 -0
  58. package/dist/components/Timeline/TimelineLayerChildren.js +129 -0
  59. package/dist/components/Timeline/TimelineNumberField.js +13 -5
  60. package/dist/components/Timeline/TimelinePinchZoom.js +14 -4
  61. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +8 -4
  62. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  63. package/dist/components/Timeline/TimelineSequence.js +54 -73
  64. package/dist/components/Timeline/TimelineSequenceItem.js +16 -36
  65. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +22 -10
  66. package/dist/components/Timeline/TimelineSlider.js +2 -2
  67. package/dist/components/Timeline/TimelineTickFormatProvider.d.ts +8 -0
  68. package/dist/components/Timeline/TimelineTickFormatProvider.js +16 -0
  69. package/dist/components/Timeline/TimelineTimeIndicators.js +7 -3
  70. package/dist/components/Timeline/TimelineVideoInfo.js +7 -3
  71. package/dist/components/Timeline/TimelineWidthProvider.js +15 -8
  72. package/dist/components/Timeline/TimelineZoomControls.js +25 -8
  73. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -2
  74. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  75. package/dist/components/Timeline/timeline-scroll-logic.d.ts +1 -0
  76. package/dist/components/Timeline/timeline-scroll-logic.js +21 -17
  77. package/dist/components/Timeline/use-delete-timeline-items.d.ts +1 -0
  78. package/dist/components/Timeline/use-delete-timeline-items.js +118 -0
  79. package/dist/components/Timeline/use-timeline-asset-drop.js +8 -14
  80. package/dist/components/UpdateStatusContext.d.ts +5 -0
  81. package/dist/components/UpdateStatusContext.js +53 -2
  82. package/dist/components/UpdatesSettings.js +25 -4
  83. package/dist/components/WebMcp.js +87 -8
  84. package/dist/components/ZoomPersistor.js +2 -2
  85. package/dist/components/composition-drag-data.d.ts +36 -0
  86. package/dist/components/composition-drag-data.js +232 -0
  87. package/dist/components/composition-selector-drag-data.d.ts +27 -0
  88. package/dist/components/composition-selector-drag-data.js +80 -0
  89. package/dist/components/drop-handler-data.d.ts +2 -1
  90. package/dist/components/drop-handler-data.js +6 -4
  91. package/dist/components/effect-drag-and-drop.d.ts +2 -5
  92. package/dist/components/handle-drop.js +6 -2
  93. package/dist/components/import-assets.d.ts +7 -14
  94. package/dist/components/import-assets.js +11 -1
  95. package/dist/components/parse-caption-file.d.ts +5 -0
  96. package/dist/components/parse-caption-file.js +63 -0
  97. package/dist/error-overlay/current-error.d.ts +13 -0
  98. package/dist/error-overlay/current-error.js +21 -0
  99. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +5 -1
  100. package/dist/esm/chunk-emw4k5b0.js +99527 -0
  101. package/dist/esm/{chunk-1fkq5bfq.js → chunk-vkrvnx2h.js} +20116 -16283
  102. package/dist/esm/index.mjs +27 -9
  103. package/dist/esm/internals.mjs +17408 -13426
  104. package/dist/esm/previewEntry.mjs +17285 -13216
  105. package/dist/esm/renderEntry.mjs +1 -1
  106. package/dist/helpers/create-folder-tree.js +2 -5
  107. package/dist/helpers/document-title.d.ts +2 -0
  108. package/dist/helpers/document-title.js +14 -3
  109. package/dist/helpers/get-preview-file-type.js +22 -3
  110. package/dist/helpers/get-timeline-max-zoom.d.ts +34 -28
  111. package/dist/helpers/get-timeline-max-zoom.js +46 -29
  112. package/dist/helpers/inserted-element-selection.d.ts +2 -1
  113. package/dist/helpers/install-fiber-sequence-order-observer.d.ts +37 -0
  114. package/dist/helpers/install-fiber-sequence-order-observer.js +109 -0
  115. package/dist/helpers/open-in-editor.js +2 -1
  116. package/dist/helpers/use-menu-structure.js +2 -2
  117. package/dist/helpers/use-runtime-values.d.ts +1 -1
  118. package/dist/helpers/use-runtime-values.js +5 -4
  119. package/dist/helpers/use-sync-external-store.d.ts +3 -0
  120. package/dist/helpers/use-sync-external-store.js +5 -0
  121. package/dist/index.d.ts +1 -0
  122. package/dist/index.js +3 -1
  123. package/dist/previewEntry.js +2 -0
  124. package/dist/state/modals.d.ts +16 -2
  125. package/dist/state/timeline-sequence-hover.js +3 -2
  126. package/dist/state/timeline-zoom.d.ts +0 -1
  127. package/dist/state/timeline-zoom.js +13 -6
  128. package/package.json +17 -17
  129. package/dist/helpers/sort-by-nonce-history.d.ts +0 -1
  130. package/dist/helpers/sort-by-nonce-history.js +0 -6
@@ -53,7 +53,6 @@ const transform_3d_mode_1 = require("../../state/transform-3d-mode");
53
53
  const CompositionOrStillIcon_1 = require("../CompositionOrStillIcon");
54
54
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
55
55
  const ContextMenu_1 = require("../ContextMenu");
56
- const delete_jsx_node_api_1 = require("../delete-jsx-node-api");
57
56
  const effect_drag_and_drop_1 = require("../effect-drag-and-drop");
58
57
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
59
58
  const InitialCompositionLoader_1 = require("../InitialCompositionLoader");
@@ -62,7 +61,6 @@ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
62
61
  const reorder_sequence_api_1 = require("../reorder-sequence-api");
63
62
  const selected_outline_types_1 = require("../selected-outline-types");
64
63
  const use_select_asset_1 = require("../use-select-asset");
65
- const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
66
64
  const disable_sequence_interactivity_1 = require("./disable-sequence-interactivity");
67
65
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
68
66
  const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-items");
@@ -72,11 +70,13 @@ const timeline_asset_link_1 = require("./timeline-asset-link");
72
70
  const TimelineDuplicateCount_1 = require("./TimelineDuplicateCount");
73
71
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
74
72
  const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
73
+ const TimelineLayerChildren_1 = require("./TimelineLayerChildren");
75
74
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
76
75
  const TimelineMediaInfo_1 = require("./TimelineMediaInfo");
77
76
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
78
77
  const TimelineSelection_1 = require("./TimelineSelection");
79
78
  const TimelineSequenceName_1 = require("./TimelineSequenceName");
79
+ const use_delete_timeline_items_1 = require("./use-delete-timeline-items");
80
80
  const use_open_sequence_in_apps_1 = require("./use-open-sequence-in-apps");
81
81
  const use_rename_sequence_1 = require("./use-rename-sequence");
82
82
  const use_sequence_freeze_frame_menu_item_1 = require("./use-sequence-freeze-frame-menu-item");
@@ -194,6 +194,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
194
194
  const { isHighestContext } = (0, use_keybinding_1.useKeybinding)();
195
195
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
196
196
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
197
+ const deleteTimelineItems = (0, use_delete_timeline_items_1.useDeleteTimelineItems)();
197
198
  const { onSelect, selectable, selected } = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
198
199
  const { selectItem, selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
199
200
  const selectedSequenceNodePathInfos = (0, react_1.useMemo)(() => {
@@ -261,41 +262,17 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
261
262
  }
262
263
  (0, duplicate_selected_timeline_item_1.duplicateSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
263
264
  }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
264
- const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => {
265
- if (deleteDisabled || !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
265
+ const onDeleteSequenceFromSource = (0, react_1.useCallback)(() => {
266
+ if (deleteDisabled ||
267
+ !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) ||
268
+ !nodePath ||
269
+ !nodePathInfo) {
266
270
  return;
267
271
  }
268
- if (nodePathInfo && nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
269
- const shouldDelete = await confirm({
270
- title: 'Delete sequence?',
271
- message: 'This sequence is programmatically duplicated ' +
272
- nodePathInfo.numberOfSequencesWithThisNodePath +
273
- ' times in the code. Deleting removes all instances. Continue?',
274
- confirmLabel: 'Delete',
275
- });
276
- if (!shouldDelete) {
277
- return;
278
- }
279
- }
280
- try {
281
- const result = await (0, delete_jsx_node_api_1.deleteJsxNode)({
282
- nodes: [
283
- {
284
- fileName: validatedLocation.source,
285
- nodePath: nodePath.nodePath,
286
- },
287
- ],
288
- });
289
- if (!result.success) {
290
- (0, NotificationCenter_1.showNotification)(result.reason, 4000);
291
- }
292
- }
293
- catch (err) {
294
- (0, NotificationCenter_1.showNotification)(err.message, 4000);
295
- }
272
+ deleteTimelineItems([{ type: 'sequence', nodePathInfo }]);
296
273
  }, [
297
- confirm,
298
274
  deleteDisabled,
275
+ deleteTimelineItems,
299
276
  nodePath,
300
277
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
301
278
  nodePathInfo,
@@ -304,8 +281,11 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
304
281
  if (!previewInteractive || selectedSequenceNodePathInfos === null) {
305
282
  return;
306
283
  }
307
- (0, delete_selected_timeline_item_1.deleteSequencesFromSource)(selectedSequenceNodePathInfos, confirm).catch(() => undefined);
308
- }, [confirm, previewInteractive, selectedSequenceNodePathInfos]);
284
+ deleteTimelineItems(selectedSequenceNodePathInfos.map((selectedNodePathInfo) => ({
285
+ type: 'sequence',
286
+ nodePathInfo: selectedNodePathInfo,
287
+ })));
288
+ }, [deleteTimelineItems, previewInteractive, selectedSequenceNodePathInfos]);
309
289
  const onDisableSequenceInteractivity = (0, react_1.useCallback)(() => {
310
290
  if (disableInteractivityDisabled ||
311
291
  !nodePath ||
@@ -944,7 +924,7 @@ const TimelineSequenceItemInner = ({ afterDropLineOffset, connectedCompositions,
944
924
  clientId: previewServerState.clientId,
945
925
  });
946
926
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
947
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: rowStyle, selected: selected, selectable: selectable, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, hovered: hovered, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
927
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineLayerChildren_1.TimelineLayerChildrenToggle, { sequence: sequence }), style: rowStyle, selected: selected, selectable: selectable, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, hovered: hovered, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
948
928
  jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { color: (0, TimelineSelection_1.getTimelineColor)(false, false), composition: connectedCompositions[0], style: connectedCompositionIconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
949
929
  ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
950
930
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, sequence: sequence })
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.TimelineSequenceRightEdgeDragHandle = exports.useTimelineSequenceFromDrag = exports.TimelineSequenceLeftEdgeDragHandle = exports.getTimelineSequenceFromDragTargets = exports.getTimelineSequenceLeftEdgeDragTargets = exports.getTimelineSequenceDurationDragTargets = exports.getTimelineSequenceFromDragKeyframeMoves = exports.getTimelineSequenceFromDragChanges = exports.getTimelineSequenceFromDragDelta = exports.getTimelineSequenceFromDragValue = exports.getTimelineSequenceDurationDragChanges = exports.getTimelineSequenceLeftEdgeDragChanges = exports.getTimelineSequenceLeftEdgeDragValues = exports.getTimelineSequenceLeftEdgeDragDelta = exports.getTimelineSequenceDurationDragValue = exports.isTimelineSequenceLeftEdgeDraggable = exports.canResizeTimelineSequenceDuration = exports.isTimelineSequenceDurationDraggable = exports.isCascadingSequence = exports.isTransitionSeriesSequence = exports.timelineSequenceFromDragSnapThresholdPx = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const canvas_1 = require("@remotion/canvas");
38
39
  const studio_shared_1 = require("@remotion/studio-shared");
39
40
  const react_1 = __importStar(require("react"));
40
41
  const remotion_1 = require("remotion");
@@ -43,19 +44,20 @@ const calculate_timeline_1 = require("../../helpers/calculate-timeline");
43
44
  const client_id_1 = require("../../helpers/client-id");
44
45
  const colors_1 = require("../../helpers/colors");
45
46
  const pointer_session_1 = require("../../helpers/pointer-session");
46
- const sort_by_nonce_history_1 = require("../../helpers/sort-by-nonce-history");
47
47
  const timeline_layout_1 = require("../../helpers/timeline-layout");
48
48
  const editor_snapping_1 = require("../../state/editor-snapping");
49
49
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
50
50
  const save_sequence_prop_1 = require("./save-sequence-prop");
51
51
  const TimelineSelection_1 = require("./TimelineSelection");
52
- const HANDLE_WIDTH = 6;
52
+ const HANDLE_INSET = 6;
53
+ const HANDLE_OUTSET = 8;
53
54
  exports.timelineSequenceFromDragSnapThresholdPx = 10;
54
55
  const baseStyle = {
55
56
  position: 'absolute',
56
57
  top: 0,
57
58
  bottom: 0,
58
- width: HANDLE_WIDTH,
59
+ // Keep the middle half of narrow layers available for moving.
60
+ width: `calc(${HANDLE_OUTSET}px + min(${HANDLE_INSET}px, 25%))`,
59
61
  cursor: 'ew-resize',
60
62
  zIndex: 1,
61
63
  touchAction: 'none',
@@ -168,9 +170,9 @@ const getMinimumSequenceDuration = ({ sequence, sequences, }) => {
168
170
  if (!(0, exports.isTransitionSeriesSequence)(sequence)) {
169
171
  return 1;
170
172
  }
171
- const siblings = (0, sort_by_nonce_history_1.sortItemsByNonceHistory)(sequences.filter((candidate) => candidate.parent === sequence.parent &&
173
+ const siblings = (0, canvas_1.sortItemsByCommitOrder)(sequences.filter((candidate) => candidate.parent === sequence.parent &&
172
174
  ((0, exports.isTransitionSeriesSequence)(candidate) ||
173
- isTransitionSeriesTransition(candidate))));
175
+ isTransitionSeriesTransition(candidate))), (candidate) => candidate.timelineOrder);
174
176
  const sequenceIndex = siblings.findIndex((candidate) => candidate.id === sequence.id);
175
177
  if (sequenceIndex === -1) {
176
178
  return 1;
@@ -822,6 +824,8 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
822
824
  if (!dragState || e.pointerId !== dragState.pointerId) {
823
825
  return;
824
826
  }
827
+ // Include the release position even if the final pointermove was skipped.
828
+ onMove(e);
825
829
  finishDrag(true);
826
830
  };
827
831
  const onCancel = (e) => {
@@ -840,7 +844,9 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
840
844
  captureTarget: activeDragState.target,
841
845
  onMove,
842
846
  onEnd: (reason, endEvent) => {
843
- if ((reason === 'pointerup' || reason === 'buttons-released') &&
847
+ if ((reason === 'pointerup' ||
848
+ reason === 'buttons-released' ||
849
+ (reason === 'lostpointercapture' && (endEvent === null || endEvent === void 0 ? void 0 : endEvent.buttons) === 0)) &&
844
850
  endEvent) {
845
851
  onUp(endEvent);
846
852
  }
@@ -855,7 +861,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
855
861
  }, [dragging, finishDrag]);
856
862
  const style = {
857
863
  ...baseStyle,
858
- left: 0,
864
+ left: -HANDLE_OUTSET,
859
865
  background: colors_1.TRANSPARENT,
860
866
  };
861
867
  return (jsx_runtime_1.jsx("div", { role: "separator", "aria-orientation": "vertical", title: "Drag to trim start", style: style, onPointerDown: onPointerDown }));
@@ -1041,7 +1047,9 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
1041
1047
  },
1042
1048
  onEnd: (reason, endEvent) => {
1043
1049
  stopPointerSessionRef.current = null;
1044
- finishDrag((reason === 'pointerup' || reason === 'buttons-released') &&
1050
+ finishDrag((reason === 'pointerup' ||
1051
+ reason === 'buttons-released' ||
1052
+ (reason === 'lostpointercapture' && (endEvent === null || endEvent === void 0 ? void 0 : endEvent.buttons) === 0)) &&
1045
1053
  endEvent !== null);
1046
1054
  },
1047
1055
  });
@@ -1218,6 +1226,8 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, windowWidth, t
1218
1226
  if (!dragState || e.pointerId !== dragState.pointerId) {
1219
1227
  return;
1220
1228
  }
1229
+ // Include the release position even if the final pointermove was skipped.
1230
+ onMove(e);
1221
1231
  finishDrag(true);
1222
1232
  };
1223
1233
  const onCancel = (e) => {
@@ -1236,7 +1246,9 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, windowWidth, t
1236
1246
  captureTarget: activeDragState.target,
1237
1247
  onMove,
1238
1248
  onEnd: (reason, endEvent) => {
1239
- if ((reason === 'pointerup' || reason === 'buttons-released') &&
1249
+ if ((reason === 'pointerup' ||
1250
+ reason === 'buttons-released' ||
1251
+ (reason === 'lostpointercapture' && (endEvent === null || endEvent === void 0 ? void 0 : endEvent.buttons) === 0)) &&
1240
1252
  endEvent) {
1241
1253
  onUp(endEvent);
1242
1254
  }
@@ -1251,7 +1263,7 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, windowWidth, t
1251
1263
  }, [dragging, finishDrag]);
1252
1264
  const style = {
1253
1265
  ...baseStyle,
1254
- right: 0,
1266
+ right: -HANDLE_OUTSET,
1255
1267
  background: colors_1.TRANSPARENT,
1256
1268
  };
1257
1269
  return (jsx_runtime_1.jsx("div", { role: "separator", "aria-orientation": "vertical", title: "Drag to change duration", style: style, onPointerDown: onPointerDown }));
@@ -60,8 +60,8 @@ const TimelineSliderInner = () => {
60
60
  throw new Error('Unexpectedly did not have timeline width');
61
61
  }
62
62
  const zoomLevel = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition'
63
- ? ((_a = zoomMap[canvasContent.compositionId]) !== null && _a !== void 0 ? _a : timeline_zoom_1.TIMELINE_MIN_ZOOM)
64
- : timeline_zoom_1.TIMELINE_MIN_ZOOM;
63
+ ? ((_a = zoomMap[canvasContent.compositionId]) !== null && _a !== void 0 ? _a : null)
64
+ : null;
65
65
  (0, react_1.useLayoutEffect)(() => {
66
66
  var _a;
67
67
  const el = ref.current;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export declare const TimelineTickFormatContext: React.Context<{
3
+ showFrames: boolean;
4
+ setShowFrames: React.Dispatch<React.SetStateAction<boolean>>;
5
+ }>;
6
+ export declare const TimelineTickFormatProvider: React.FC<{
7
+ readonly children: React.ReactNode;
8
+ }>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineTickFormatProvider = exports.TimelineTickFormatContext = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const STORAGE_KEY = 'remotion.timelineShowFrames';
7
+ exports.TimelineTickFormatContext = (0, react_1.createContext)({ showFrames: false, setShowFrames: () => undefined });
8
+ const TimelineTickFormatProvider = ({ children }) => {
9
+ const [showFrames, setShowFrames] = (0, react_1.useState)(() => localStorage.getItem(STORAGE_KEY) === 'true');
10
+ (0, react_1.useEffect)(() => {
11
+ localStorage.setItem(STORAGE_KEY, String(showFrames));
12
+ }, [showFrames]);
13
+ const value = (0, react_1.useMemo)(() => ({ showFrames, setShowFrames }), [showFrames]);
14
+ return (jsx_runtime_1.jsx(exports.TimelineTickFormatContext.Provider, { value: value, children: children }));
15
+ };
16
+ exports.TimelineTickFormatProvider = TimelineTickFormatProvider;
@@ -44,6 +44,7 @@ const TimeValue_1 = require("../TimeValue");
44
44
  const timeline_refs_1 = require("./timeline-refs");
45
45
  const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
46
46
  const TimelineSelection_1 = require("./TimelineSelection");
47
+ const TimelineTickFormatProvider_1 = require("./TimelineTickFormatProvider");
47
48
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
48
49
  exports.TIMELINE_TIME_INDICATOR_HEIGHT = 39;
49
50
  const container = {
@@ -190,6 +191,7 @@ const TimelineTimeIndicators = () => {
190
191
  exports.TimelineTimeIndicators = TimelineTimeIndicators;
191
192
  const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, durationInFrames, fps }) => {
192
193
  const canvasRef = (0, react_1.useRef)(null);
194
+ const { showFrames } = (0, react_1.useContext)(TimelineTickFormatProvider_1.TimelineTickFormatContext);
193
195
  (0, react_1.useLayoutEffect)(() => {
194
196
  const canvas = canvasRef.current;
195
197
  const scrollable = timeline_refs_1.scrollableRef.current;
@@ -201,7 +203,9 @@ const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, duratio
201
203
  return;
202
204
  }
203
205
  const frameInterval = (0, timeline_scroll_logic_1.getFrameIncrementFromWidth)(durationInFrames, windowWidth);
204
- const maxTickLabelWidth = (0, render_frame_1.renderFrame)(durationInFrames - 1, fps).length *
206
+ const maxTickLabelWidth = (showFrames
207
+ ? `${durationInFrames - 1}f`
208
+ : (0, render_frame_1.renderFrame)(durationInFrames - 1, fps)).length *
205
209
  TICK_LABEL_FONT_SIZE *
206
210
  0.6;
207
211
  const tickScale = (0, exports.getTimelineTickScale)({
@@ -242,7 +246,7 @@ const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, duratio
242
246
  context.fillStyle = colors_1.LIGHT_TEXT;
243
247
  context.font = `${TICK_LABEL_FONT_SIZE}px ${getComputedStyle(canvas).fontFamily}`;
244
248
  context.textBaseline = 'top';
245
- context.fillText((0, render_frame_1.renderFrame)(frame, fps), xForFrame(frame) + TICK_LABEL_MARGIN_LEFT, 7);
249
+ context.fillText(showFrames ? `${Math.round(frame)}f` : (0, render_frame_1.renderFrame)(frame, fps), xForFrame(frame) + TICK_LABEL_MARGIN_LEFT, 7);
246
250
  context.fillStyle = colors_1.WHITE_ALPHA_15;
247
251
  }
248
252
  }
@@ -286,7 +290,7 @@ const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, duratio
286
290
  scrollable.removeEventListener('scroll', onScroll);
287
291
  resizeObserver.disconnect();
288
292
  };
289
- }, [durationInFrames, fps, windowWidth]);
293
+ }, [durationInFrames, fps, showFrames, windowWidth]);
290
294
  const style = (0, react_1.useMemo)(() => {
291
295
  return {
292
296
  ...container,
@@ -53,6 +53,7 @@ const filmstripContainerStyle = {
53
53
  height: timeline_layout_1.TIMELINE_LAYER_FILMSTRIP_HEIGHT,
54
54
  backgroundColor: colors_1.BLACK_ALPHA_30,
55
55
  display: 'flex',
56
+ overflow: 'hidden',
56
57
  borderTopLeftRadius: 2,
57
58
  fontSize: 10,
58
59
  fontFamily: 'Arial, Helvetica',
@@ -86,8 +87,8 @@ const TimelineVideoInfoSegment = ({ src, visualizationWidth, startMediaFrom, med
86
87
  const canvas = document.createElement('canvas');
87
88
  canvas.width = Math.ceil(visualizationWidth * pixelRatio);
88
89
  canvas.height = Math.ceil(timeline_layout_1.TIMELINE_LAYER_FILMSTRIP_HEIGHT * pixelRatio);
89
- canvas.style.width = visualizationWidth + 'px';
90
- canvas.style.height = timeline_layout_1.TIMELINE_LAYER_FILMSTRIP_HEIGHT + 'px';
90
+ canvas.style.width = canvas.width / pixelRatio + 'px';
91
+ canvas.style.height = canvas.height / pixelRatio + 'px';
91
92
  const ctx = canvas.getContext('2d');
92
93
  if (!ctx) {
93
94
  return;
@@ -194,7 +195,10 @@ const TimelineVideoInfoSegment = ({ src, visualizationWidth, startMediaFrom, med
194
195
  // desired-timestamp -> filled-timestamp
195
196
  const filledSlots = new Map();
196
197
  const { fromSeconds, toSeconds } = times;
197
- const targetWidth = targetCanvas.width;
198
+ // Keep the time-to-pixel scale independent of the integer canvas backing size.
199
+ const targetWidth = tiledLoop
200
+ ? tiledLoop.loopWidth * pixelRatio
201
+ : visualizationWidth * pixelRatio;
198
202
  const repeatTarget = () => {
199
203
  if (!tiledLoop) {
200
204
  return;
@@ -5,6 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const player_1 = require("@remotion/player");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
+ const get_timeline_max_zoom_1 = require("../../helpers/get-timeline-max-zoom");
8
9
  const timeline_zoom_1 = require("../../state/timeline-zoom");
9
10
  const timeline_refs_1 = require("./timeline-refs");
10
11
  exports.TimelineWidthContext = (0, react_1.createContext)(null);
@@ -15,18 +16,24 @@ const TimelineWidthProvider = ({ children }) => {
15
16
  });
16
17
  const { zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
17
18
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
19
+ const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
18
20
  const width = (0, react_1.useMemo)(() => {
19
21
  var _a, _b;
20
- var _c, _d, _e;
21
- const zoom = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition'
22
- ? ((_c = zoomMap[canvasContent.compositionId]) !== null && _c !== void 0 ? _c : timeline_zoom_1.TIMELINE_MIN_ZOOM)
23
- : timeline_zoom_1.TIMELINE_MIN_ZOOM;
24
- const scrollableWidth = (_d = size === null || size === void 0 ? void 0 : size.width) !== null && _d !== void 0 ? _d : (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth;
22
+ var _c, _d, _e, _f;
23
+ const scrollableWidth = (_c = size === null || size === void 0 ? void 0 : size.width) !== null && _c !== void 0 ? _c : (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth;
25
24
  if (scrollableWidth === undefined) {
26
- return (_e = (_b = timeline_refs_1.sliderAreaRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) !== null && _e !== void 0 ? _e : null;
25
+ return (_d = (_b = timeline_refs_1.sliderAreaRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) !== null && _d !== void 0 ? _d : null;
27
26
  }
28
- return scrollableWidth * zoom;
29
- }, [canvasContent, size === null || size === void 0 ? void 0 : size.width, zoomMap]);
27
+ const durationInFrames = (_e = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _e !== void 0 ? _e : 1;
28
+ const zoom = (0, get_timeline_max_zoom_1.getTimelineZoom)({
29
+ durationInFrames,
30
+ timelineViewportWidth: scrollableWidth,
31
+ zoom: (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition'
32
+ ? ((_f = zoomMap[canvasContent.compositionId]) !== null && _f !== void 0 ? _f : null)
33
+ : null,
34
+ });
35
+ return (0, get_timeline_max_zoom_1.getTimelineWidth)({ durationInFrames, zoom });
36
+ }, [canvasContent, size === null || size === void 0 ? void 0 : size.width, videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames, zoomMap]);
30
37
  return (jsx_runtime_1.jsx(exports.TimelineWidthContext.Provider, { value: width, children: children }));
31
38
  };
32
39
  exports.TimelineWidthProvider = TimelineWidthProvider;
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.TimelineZoomControls = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const player_1 = require("@remotion/player");
38
39
  const react_1 = __importStar(require("react"));
39
40
  const remotion_1 = require("remotion");
40
41
  const colors_1 = require("../../helpers/colors");
@@ -45,6 +46,7 @@ const timeline_zoom_1 = require("../../state/timeline-zoom");
45
46
  const z_index_1 = require("../../state/z-index");
46
47
  const ControlButton_1 = require("../ControlButton");
47
48
  const layout_1 = require("../layout");
49
+ const timeline_refs_1 = require("./timeline-refs");
48
50
  const TIMELINE_ZOOM_BUTTON_FACTOR = 1.2;
49
51
  const container = {
50
52
  color: colors_1.BLACK,
@@ -55,10 +57,11 @@ const container = {
55
57
  const buttonStyle = {
56
58
  fontSize: 24,
57
59
  };
58
- const TimelineZoomSlider = ({ maxWidth, maxZoom }) => {
59
- var _a;
60
+ const TimelineZoomSlider = ({ maxWidth, minZoom, timelineViewportWidth }) => {
61
+ var _a, _b;
60
62
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
61
63
  const { setZoom, zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
64
+ const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
62
65
  const { tabIndex } = (0, z_index_1.useZIndex)();
63
66
  const isStill = (0, is_current_selected_still_1.useIsStill)();
64
67
  const onChange = (0, react_1.useCallback)((e) => {
@@ -67,26 +70,40 @@ const TimelineZoomSlider = ({ maxWidth, maxZoom }) => {
67
70
  }
68
71
  setZoom(canvasContent.compositionId, () => (0, get_timeline_max_zoom_1.sliderValueToTimelineZoom)({
69
72
  sliderValue: Number(e.target.value),
70
- maxZoom,
73
+ minZoom,
71
74
  }), {
72
75
  anchorFrame: null,
73
76
  anchorContentX: null,
74
77
  });
75
- }, [canvasContent, maxZoom, setZoom]);
78
+ }, [canvasContent, minZoom, setZoom]);
76
79
  if (isStill ||
77
80
  canvasContent === null ||
78
81
  canvasContent.type !== 'composition') {
79
82
  return null;
80
83
  }
81
- const zoom = (_a = zoomMap[canvasContent.compositionId]) !== null && _a !== void 0 ? _a : get_timeline_max_zoom_1.TIMELINE_MIN_ZOOM;
82
- return (jsx_runtime_1.jsx("input", { style: maxWidth === undefined ? undefined : { maxWidth }, title: `Timeline zoom (${zoom}x)`, alt: `Timeline zoom (${zoom}x)`, type: "range", min: get_timeline_max_zoom_1.TIMELINE_ZOOM_SLIDER_PROPS.min, max: get_timeline_max_zoom_1.TIMELINE_ZOOM_SLIDER_PROPS.max, step: get_timeline_max_zoom_1.TIMELINE_ZOOM_SLIDER_PROPS.step, value: (0, get_timeline_max_zoom_1.timelineZoomToSliderValue)({ zoom, maxZoom }), onChange: onChange, className: "__remotion-timeline-slider", tabIndex: tabIndex }));
84
+ const zoom = (0, get_timeline_max_zoom_1.getTimelineZoom)({
85
+ durationInFrames: (_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 1,
86
+ timelineViewportWidth,
87
+ zoom: (_b = zoomMap[canvasContent.compositionId]) !== null && _b !== void 0 ? _b : null,
88
+ });
89
+ const roundedZoom = Math.round(zoom * 100) / 100;
90
+ return (jsx_runtime_1.jsx("input", { style: maxWidth === undefined ? undefined : { maxWidth }, title: `Timeline zoom (${roundedZoom}px/frame)`, alt: `Timeline zoom (${roundedZoom}px/frame)`, type: "range", min: get_timeline_max_zoom_1.TIMELINE_ZOOM_SLIDER_PROPS.min, max: get_timeline_max_zoom_1.TIMELINE_ZOOM_SLIDER_PROPS.max, step: get_timeline_max_zoom_1.TIMELINE_ZOOM_SLIDER_PROPS.step, value: (0, get_timeline_max_zoom_1.timelineZoomToSliderValue)({ zoom, minZoom }), onChange: onChange, className: "__remotion-timeline-slider", tabIndex: tabIndex }));
83
91
  };
84
92
  const TimelineZoomControlsInner = ({ sliderMaxWidth }) => {
85
93
  var _a;
94
+ var _b, _c, _d;
86
95
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
87
96
  const { setZoom } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
88
97
  const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
89
- const maxZoom = (0, get_timeline_max_zoom_1.getTimelineMaxZoom)((_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 1);
98
+ const timelineSize = player_1.PlayerInternals.useElementSize(timeline_refs_1.scrollableRef, {
99
+ triggerOnWindowResize: true,
100
+ shouldApplyCssTransforms: true,
101
+ });
102
+ const timelineViewportWidth = (_c = (_b = timelineSize === null || timelineSize === void 0 ? void 0 : timelineSize.width) !== null && _b !== void 0 ? _b : (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _c !== void 0 ? _c : 0;
103
+ const minZoom = (0, get_timeline_max_zoom_1.getTimelineMinZoom)({
104
+ durationInFrames: (_d = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _d !== void 0 ? _d : 1,
105
+ timelineViewportWidth,
106
+ });
90
107
  const onMinusClicked = (0, react_1.useCallback)(() => {
91
108
  if (canvasContent === null || canvasContent.type !== 'composition') {
92
109
  return;
@@ -106,7 +123,7 @@ const TimelineZoomControlsInner = ({ sliderMaxWidth }) => {
106
123
  return null;
107
124
  }
108
125
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
109
- jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onMinusClicked, style: buttonStyle, title: "Zoom out timeline", role: 'ControlButton', type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomOutIcon, { color: color }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineZoomSlider, { maxWidth: sliderMaxWidth, maxZoom: maxZoom }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onPlusClicked, style: buttonStyle, title: "Zoom in timeline", role: 'button', type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomIcon, { color: color }) })
126
+ jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onMinusClicked, style: buttonStyle, title: "Zoom out timeline", role: 'ControlButton', type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomOutIcon, { color: color }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineZoomSlider, { maxWidth: sliderMaxWidth, minZoom: minZoom, timelineViewportWidth: timelineViewportWidth }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { onClick: onPlusClicked, style: buttonStyle, title: "Zoom in timeline", role: 'button', type: "button", children: (color) => jsx_runtime_1.jsx(canvas_zoom_1.CanvasZoomIcon, { color: color }) })
110
127
  ] }));
111
128
  };
112
129
  exports.TimelineZoomControls = react_1.default.memo(TimelineZoomControlsInner);
@@ -52,11 +52,11 @@ const deleteSequencesFromSource = async (nodePathInfos, confirm) => {
52
52
  if (!result.success) {
53
53
  (0, NotificationCenter_1.showNotification)(result.reason, 4000);
54
54
  }
55
- return true;
55
+ return result.success;
56
56
  })
57
57
  .catch((err) => {
58
58
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
59
- return true;
59
+ return false;
60
60
  });
61
61
  };
62
62
  exports.deleteSequencesFromSource = deleteSequencesFromSource;
@@ -243,6 +243,7 @@ const formatTimelineFieldValueForDisplay = ({ fieldSchema, value, }) => {
243
243
  case 'color':
244
244
  case 'enum':
245
245
  case 'font-family':
246
+ case 'font-weight':
246
247
  case 'hidden':
247
248
  return formatUnknownTimelineValueForDisplay(value);
248
249
  default:
@@ -3,6 +3,7 @@ export declare const canScrollTimelineIntoDirection: () => {
3
3
  canScrollLeft: boolean;
4
4
  };
5
5
  export declare const SCROLL_INCREMENT = 200;
6
+ export declare const getTimelineContentWidth: () => number;
6
7
  export declare const EDGE_SCROLL_VERTICAL_INCREMENT = 60;
7
8
  export type TimelineEdgeScrollDirections = {
8
9
  x: 'left' | 'right' | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prepareToPreserveTimelineCursor = exports.getScrollLeftToKeepCursorInPlace = exports.viewportClientXToScrollContentX = exports.getFrameFromTimelineDrop = exports.getFrameFromX = exports.getFrameWhileScrollingRight = exports.getFrameIncrementFromWidth = exports.getScrollPositionForCursorOnRightEdge = exports.getScrollPositionForCursorOnLeftEdge = exports.scrollToTimelineXOffset = exports.ensureFrameIsInViewport = exports.isCursorInViewport = exports.getFrameWhileScrollingLeft = exports.startTimelineEdgeAutoScroll = exports.EDGE_SCROLL_VERTICAL_INCREMENT = exports.SCROLL_INCREMENT = exports.canScrollTimelineIntoDirection = void 0;
3
+ exports.prepareToPreserveTimelineCursor = exports.getScrollLeftToKeepCursorInPlace = exports.viewportClientXToScrollContentX = exports.getFrameFromTimelineDrop = exports.getFrameFromX = exports.getFrameWhileScrollingRight = exports.getFrameIncrementFromWidth = exports.getScrollPositionForCursorOnRightEdge = exports.getScrollPositionForCursorOnLeftEdge = exports.scrollToTimelineXOffset = exports.ensureFrameIsInViewport = exports.isCursorInViewport = exports.getFrameWhileScrollingLeft = exports.startTimelineEdgeAutoScroll = exports.EDGE_SCROLL_VERTICAL_INCREMENT = exports.getTimelineContentWidth = exports.SCROLL_INCREMENT = exports.canScrollTimelineIntoDirection = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const timeline_layout_1 = require("../../helpers/timeline-layout");
6
6
  const imperative_state_1 = require("./imperative-state");
@@ -15,6 +15,12 @@ const canScrollTimelineIntoDirection = () => {
15
15
  };
16
16
  exports.canScrollTimelineIntoDirection = canScrollTimelineIntoDirection;
17
17
  exports.SCROLL_INCREMENT = 200;
18
+ const getTimelineContentWidth = () => {
19
+ var _a, _b;
20
+ var _c, _d;
21
+ return ((_d = (_c = (_a = timeline_refs_1.sliderAreaRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _c !== void 0 ? _c : (_b = timeline_refs_1.scrollableRef.current) === null || _b === void 0 ? void 0 : _b.scrollWidth) !== null && _d !== void 0 ? _d : 0);
22
+ };
23
+ exports.getTimelineContentWidth = getTimelineContentWidth;
18
24
  exports.EDGE_SCROLL_VERTICAL_INCREMENT = 60;
19
25
  const EDGE_SCROLL_INTERVAL_MS = 100;
20
26
  // Once edge-scrolling has started, the pointer must move this many pixels
@@ -169,10 +175,10 @@ const getFrameWhileScrollingLeft = ({ durationInFrames, width, }) => {
169
175
  };
170
176
  exports.getFrameWhileScrollingLeft = getFrameWhileScrollingLeft;
171
177
  const isCursorInViewport = ({ frame, durationInFrames, }) => {
172
- var _a, _b;
173
- var _c, _d;
174
- const width = (_c = (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.scrollWidth) !== null && _c !== void 0 ? _c : 0;
175
- const scrollLeft = (_d = (_b = timeline_refs_1.scrollableRef.current) === null || _b === void 0 ? void 0 : _b.scrollLeft) !== null && _d !== void 0 ? _d : 0;
178
+ var _a;
179
+ var _b;
180
+ const width = (0, exports.getTimelineContentWidth)();
181
+ const scrollLeft = (_b = (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.scrollLeft) !== null && _b !== void 0 ? _b : 0;
176
182
  const scrollPosOnRightEdge = (0, exports.getScrollPositionForCursorOnRightEdge)({
177
183
  nextFrame: frame,
178
184
  durationInFrames,
@@ -194,14 +200,14 @@ const isCursorInViewport = ({ frame, durationInFrames, }) => {
194
200
  };
195
201
  exports.isCursorInViewport = isCursorInViewport;
196
202
  const ensureFrameIsInViewport = ({ direction, durationInFrames, frame, }) => {
197
- var _a, _b, _c;
198
- var _d, _e;
203
+ var _a, _b;
204
+ var _c;
199
205
  // Sync the imperative frame first: scrolling below triggers the scroll
200
206
  // listener in TimelineSlider, which reads the frame imperatively.
201
207
  (0, imperative_state_1.setCurrentFrame)(frame);
202
208
  (_a = TimelineSlider_1.redrawTimelineSliderFast.current) === null || _a === void 0 ? void 0 : _a.draw(frame);
203
- const width = (_d = (_b = timeline_refs_1.scrollableRef.current) === null || _b === void 0 ? void 0 : _b.scrollWidth) !== null && _d !== void 0 ? _d : 0;
204
- const scrollLeft = (_e = (_c = timeline_refs_1.scrollableRef.current) === null || _c === void 0 ? void 0 : _c.scrollLeft) !== null && _e !== void 0 ? _e : 0;
209
+ const width = (0, exports.getTimelineContentWidth)();
210
+ const scrollLeft = (_c = (_b = timeline_refs_1.scrollableRef.current) === null || _b === void 0 ? void 0 : _b.scrollLeft) !== null && _c !== void 0 ? _c : 0;
205
211
  if (direction === 'fit-left') {
206
212
  const currentFrameLeft = (0, exports.getFrameFromX)({
207
213
  clientX: scrollLeft,
@@ -281,22 +287,20 @@ const getScrollPositionForCursorOnLeftEdge = ({ nextFrame, durationInFrames, })
281
287
  };
282
288
  exports.getScrollPositionForCursorOnLeftEdge = getScrollPositionForCursorOnLeftEdge;
283
289
  const getScrollPositionForCursorOnRightEdge = ({ nextFrame, durationInFrames, }) => {
284
- var _a, _b;
290
+ var _a;
285
291
  const frameIncrement = getFrameIncrement(durationInFrames);
286
292
  const framesRemaining = durationInFrames - 1 - nextFrame;
287
293
  const fromRight = framesRemaining * frameIncrement + timeline_layout_1.TIMELINE_PADDING;
288
- const scrollPos = ((_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.scrollWidth) -
294
+ const scrollPos = (0, exports.getTimelineContentWidth)() -
289
295
  fromRight -
290
- ((_b = timeline_refs_1.scrollableRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) +
296
+ ((_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) +
291
297
  timeline_layout_1.TIMELINE_PADDING +
292
298
  4; // clearfix;
293
299
  return scrollPos;
294
300
  };
295
301
  exports.getScrollPositionForCursorOnRightEdge = getScrollPositionForCursorOnRightEdge;
296
302
  const getFrameIncrement = (durationInFrames) => {
297
- var _a;
298
- var _b;
299
- const width = (_b = (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.scrollWidth) !== null && _b !== void 0 ? _b : 0;
303
+ const width = (0, exports.getTimelineContentWidth)();
300
304
  return (0, exports.getFrameIncrementFromWidth)(durationInFrames, width);
301
305
  };
302
306
  const getFrameIncrementFromWidth = (durationInFrames, width) => {
@@ -366,7 +370,7 @@ const prepareToPreserveTimelineCursor = ({ currentFrame, currentDurationInFrames
366
370
  if (!current) {
367
371
  return () => undefined;
368
372
  }
369
- const oldTimelineWidth = current.scrollWidth;
373
+ const oldTimelineWidth = (0, exports.getTimelineContentWidth)();
370
374
  const oldScrollLeft = current.scrollLeft;
371
375
  const frameIncrement = (0, exports.getFrameIncrementFromWidth)(currentDurationInFrames, oldTimelineWidth);
372
376
  const frameForScroll = anchorFrame !== null && anchorFrame !== void 0 ? anchorFrame : currentFrame;
@@ -381,7 +385,7 @@ const prepareToPreserveTimelineCursor = ({ currentFrame, currentDurationInFrames
381
385
  anchorContentX: prevCursorPosition,
382
386
  oldScrollLeft,
383
387
  oldTimelineWidth,
384
- newTimelineWidth: current.scrollWidth,
388
+ newTimelineWidth: (0, exports.getTimelineContentWidth)(),
385
389
  });
386
390
  };
387
391
  };
@@ -0,0 +1 @@
1
+ export declare const useDeleteTimelineItems: () => (selectedItemsOverride: readonly import("@remotion/canvas").CanvasSelectionItem[] | null) => void;