@remotion/studio 4.0.527 → 4.0.528

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 (258) hide show
  1. package/dist/components/AgentPrompt.js +1 -2
  2. package/dist/components/AudioWaveform.d.ts +1 -0
  3. package/dist/components/AudioWaveform.js +10 -14
  4. package/dist/components/CodeFrame.js +1 -1
  5. package/dist/components/ColorPicker/checker.d.ts +1 -1
  6. package/dist/components/CurrentAsset.js +3 -2
  7. package/dist/components/EditorRuler/Ruler.js +6 -3
  8. package/dist/components/EffectPickerModal.js +69 -43
  9. package/dist/components/ElementInstallConfirmation.js +3 -3
  10. package/dist/components/ElementLibrariesSettings.d.ts +2 -0
  11. package/dist/components/ElementLibrariesSettings.js +200 -0
  12. package/dist/components/InitialCompositionLoader.js +3 -1
  13. package/dist/components/InspectorOpenInEditor.js +13 -0
  14. package/dist/components/InspectorPanel/AlignmentControls.js +28 -9
  15. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +1 -1
  16. package/dist/components/InspectorPanel/EasingInspector.js +6 -2
  17. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -1
  18. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +1 -1
  19. package/dist/components/InspectorPanel/KeyframeInspector.js +28 -24
  20. package/dist/components/InspectorPanel/MultiSequenceNumberField.js +1 -1
  21. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -1
  22. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +30 -2
  23. package/dist/components/InspectorPanel/SequenceWrapAction.d.ts +8 -0
  24. package/dist/components/InspectorPanel/SequenceWrapAction.js +151 -0
  25. package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +2 -1
  26. package/dist/components/InspectorPanel/easing-inspector-selection.js +4 -3
  27. package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +2 -1
  28. package/dist/components/InspectorPanel/keyframe-inspector-frame.js +2 -2
  29. package/dist/components/InspectorSequenceSection.d.ts +1 -0
  30. package/dist/components/InspectorSequenceSection.js +7 -5
  31. package/dist/components/KeyboardShortcutsSettings.js +1 -1
  32. package/dist/components/Menu/styles.d.ts +2 -2
  33. package/dist/components/Modals.js +7 -6
  34. package/dist/components/ModelManager.js +10 -9
  35. package/dist/components/NewComposition/CancelButton.js +10 -4
  36. package/dist/components/NewComposition/InputDragger.d.ts +3 -1
  37. package/dist/components/NewComposition/InputDragger.js +28 -9
  38. package/dist/components/NewComposition/NewComposition.js +7 -6
  39. package/dist/components/NewComposition/RemInput.d.ts +1 -1
  40. package/dist/components/NewComposition/menu-typeahead.js +1 -1
  41. package/dist/components/Preview.js +3 -2
  42. package/dist/components/RenderModal/SchemaEditor/create-zod-values.js +1 -2
  43. package/dist/components/RenderModal/WebRenderModalPicture.js +1 -2
  44. package/dist/components/RenderQueue/CaptionQueueItem.js +14 -5
  45. package/dist/components/RenderQueue/CaptionQueueProcessor.js +30 -7
  46. package/dist/components/RenderQueue/QueueJobError.d.ts +8 -0
  47. package/dist/components/RenderQueue/QueueJobError.js +24 -0
  48. package/dist/components/RenderQueue/QueueJobErrorModal.d.ts +8 -0
  49. package/dist/components/RenderQueue/QueueJobErrorModal.js +63 -0
  50. package/dist/components/RenderQueue/RenderQueueItemCancelButton.d.ts +3 -1
  51. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +11 -4
  52. package/dist/components/RenderQueue/RenderQueueRepeat.d.ts +3 -1
  53. package/dist/components/RenderQueue/RenderQueueRepeat.js +20 -3
  54. package/dist/components/RenderQueue/VideoMattingQueueItem.js +24 -27
  55. package/dist/components/RenderQueue/VideoMattingQueueProcessor.js +68 -28
  56. package/dist/components/RenderQueue/caption-job-types.d.ts +3 -1
  57. package/dist/components/RenderQueue/context.d.ts +4 -0
  58. package/dist/components/RenderQueue/context.js +58 -8
  59. package/dist/components/RenderQueue/index.js +2 -3
  60. package/dist/components/RenderQueue/load-model-for-job.d.ts +2 -1
  61. package/dist/components/RenderQueue/load-model-for-job.js +5 -1
  62. package/dist/components/RenderQueue/video-matting-job-types.d.ts +13 -6
  63. package/dist/components/SelectedOutlineCropControls.js +2 -1
  64. package/dist/components/SelectedOutlineEditingHandles.js +9 -2
  65. package/dist/components/SelectedOutlineElement.js +9 -3
  66. package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -4
  67. package/dist/components/SelectedOutlineKeyboardControls.js +4 -22
  68. package/dist/components/SelectedOutlineOverlay.js +152 -106
  69. package/dist/components/SelectedOutlinePathPoints.d.ts +8 -0
  70. package/dist/components/SelectedOutlinePathPoints.js +433 -0
  71. package/dist/components/SelectedOutlinePolygon.js +21 -46
  72. package/dist/components/SelectedOutlineRenderer.d.ts +3 -5
  73. package/dist/components/SelectedOutlineRenderer.js +32 -136
  74. package/dist/components/SelectedOutlineTransformOriginHandle.js +3 -2
  75. package/dist/components/SelectedOutlineUvControls.js +12 -7
  76. package/dist/components/SettingsModal.js +30 -3
  77. package/dist/components/SettingsModalFooter.d.ts +1 -0
  78. package/dist/components/SettingsModalFooter.js +7 -3
  79. package/dist/components/ShowOutlinesProvider.js +1 -1
  80. package/dist/components/SkillsSettings.d.ts +0 -1
  81. package/dist/components/SkillsSettings.js +13 -14
  82. package/dist/components/Splitter/SplitterElement.js +1 -2
  83. package/dist/components/TimeValue.js +1 -1
  84. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +1 -0
  85. package/dist/components/Timeline/LoopedTimelineIndicators.js +7 -6
  86. package/dist/components/Timeline/TimelineArrayField.js +1 -1
  87. package/dist/components/Timeline/TimelineClipboardKeybindings.js +0 -1
  88. package/dist/components/Timeline/TimelineColorField.js +1 -1
  89. package/dist/components/Timeline/TimelineDragHandler.js +1 -1
  90. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  91. package/dist/components/Timeline/TimelineEffectPropItem.js +12 -5
  92. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
  93. package/dist/components/Timeline/TimelineExpandedRow.js +5 -4
  94. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
  95. package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
  96. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +1 -0
  97. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +3 -1
  98. package/dist/components/Timeline/TimelineFontFamilyField.js +12 -12
  99. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -0
  100. package/dist/components/Timeline/TimelineKeyframeControls.js +39 -28
  101. package/dist/components/Timeline/TimelineLayerChildren.js +1 -1
  102. package/dist/components/Timeline/TimelineList.js +1 -1
  103. package/dist/components/Timeline/TimelineNumberField.js +2 -4
  104. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -1
  105. package/dist/components/Timeline/TimelineSelection.d.ts +9 -9
  106. package/dist/components/Timeline/TimelineSelection.js +16 -9
  107. package/dist/components/Timeline/TimelineSequence.d.ts +3 -1
  108. package/dist/components/Timeline/TimelineSequence.js +39 -21
  109. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  110. package/dist/components/Timeline/TimelineSequenceItem.js +18 -8
  111. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +3 -0
  112. package/dist/components/Timeline/TimelineSequencePropItem.js +262 -25
  113. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +11 -13
  114. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +98 -77
  115. package/dist/components/Timeline/TimelineTextContentField.js +27 -4
  116. package/dist/components/Timeline/TimelineTimeIndicators.js +10 -5
  117. package/dist/components/Timeline/TimelineTrack.js +1 -1
  118. package/dist/components/Timeline/TimelineTrimTooltip.d.ts +11 -0
  119. package/dist/components/Timeline/TimelineTrimTooltip.js +41 -0
  120. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  121. package/dist/components/Timeline/TimelineVideoInfo.js +13 -10
  122. package/dist/components/Timeline/delete-selected-keyframe.js +22 -8
  123. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +1 -5
  124. package/dist/components/Timeline/delete-selected-timeline-item.js +7 -93
  125. package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +2 -1
  126. package/dist/components/Timeline/get-animation-item-selection-for-frame.js +7 -5
  127. package/dist/components/Timeline/get-keyframed-sequence-drag-targets.d.ts +23 -0
  128. package/dist/components/Timeline/get-keyframed-sequence-drag-targets.js +57 -0
  129. package/dist/components/Timeline/get-node-keyframes.d.ts +2 -1
  130. package/dist/components/Timeline/get-node-keyframes.js +6 -4
  131. package/dist/components/Timeline/get-playback-rate-keyframe-changes.d.ts +21 -0
  132. package/dist/components/Timeline/get-playback-rate-keyframe-changes.js +142 -0
  133. package/dist/components/Timeline/get-timeline-keyframes.d.ts +15 -2
  134. package/dist/components/Timeline/get-timeline-keyframes.js +44 -6
  135. package/dist/components/Timeline/keyframe-clipboard.js +17 -3
  136. package/dist/components/Timeline/split-selected-timeline-item.js +4 -1
  137. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  138. package/dist/components/Timeline/timeline-field-row-layout.js +1 -0
  139. package/dist/components/Timeline/use-delete-timeline-items.js +17 -11
  140. package/dist/components/Timeline/use-expanded-track-keyframe-rows.d.ts +2 -1
  141. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +3 -1
  142. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +7 -3
  143. package/dist/components/Timeline/use-timeline-keyframe-drag.js +28 -19
  144. package/dist/components/Transcription/Models.js +1 -1
  145. package/dist/components/Transcription/TranscriptionModal.js +3 -1
  146. package/dist/components/Transcription/resample-media-to-16-khz.d.ts +2 -1
  147. package/dist/components/Transcription/resample-media-to-16-khz.js +20 -2
  148. package/dist/components/UpdatesSettings.js +2 -0
  149. package/dist/components/VideoMatting/Models.js +1 -1
  150. package/dist/components/VideoMatting/VideoMattingModal.js +30 -47
  151. package/dist/components/VideoMatting/VideoMattingModalWithOptionalPackage.js +1 -1
  152. package/dist/components/WebMcp.js +22 -40
  153. package/dist/components/composition-drop-preview.js +1 -0
  154. package/dist/components/effect-drag-and-drop.d.ts +13 -5
  155. package/dist/components/effect-drag-and-drop.js +19 -4
  156. package/dist/components/get-open-in-menu-items.d.ts +2 -1
  157. package/dist/components/get-open-in-menu-items.js +17 -1
  158. package/dist/components/selected-outline-drag.d.ts +1 -6
  159. package/dist/components/selected-outline-drag.js +22 -6
  160. package/dist/components/selected-outline-geometry.d.ts +2 -18
  161. package/dist/components/selected-outline-measurement.d.ts +23 -41
  162. package/dist/components/selected-outline-measurement.js +14 -252
  163. package/dist/components/selected-outline-order.d.ts +4 -11
  164. package/dist/components/selected-outline-order.js +2 -254
  165. package/dist/components/selected-outline-snap.d.ts +1 -1
  166. package/dist/components/selected-outline-snap.js +2 -1
  167. package/dist/components/selected-outline-types.d.ts +18 -28
  168. package/dist/components/selected-outline-uv.d.ts +4 -4
  169. package/dist/components/selected-outline-uv.js +6 -111
  170. package/dist/components/sequence-props-api.js +0 -10
  171. package/dist/components/use-selected-outline-control-target.js +12 -21
  172. package/dist/components/wrap-jsx-node-api.d.ts +2 -0
  173. package/dist/components/wrap-jsx-node-api.js +13 -0
  174. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +45 -2
  175. package/dist/error-overlay/remotion-overlay/StackFrame.js +32 -3
  176. package/dist/esm/{CaptionQueueProcessor-npa6szn1.mjs → CaptionQueueProcessor-nr7hjcga.mjs} +63 -17
  177. package/dist/esm/LazyModels-ajkn7fs3.mjs +12 -0
  178. package/dist/esm/LazyModels-g1g7cf4e.mjs +12 -0
  179. package/dist/esm/{TranscriptionModal-79m5wgcj.mjs → TranscriptionModal-e18bzbkb.mjs} +15 -15
  180. package/dist/esm/{VideoMattingModal-31pew0xj.mjs → VideoMattingModal-5bz2s4rs.mjs} +47 -65
  181. package/dist/esm/{VideoMattingQueueProcessor-t1hgm2rm.mjs → VideoMattingQueueProcessor-4tkj0f4k.mjs} +69 -26
  182. package/dist/esm/{index-v4tr1bft.mjs → index-09txs1bj.mjs} +5 -0
  183. package/dist/esm/{index-n5gmcvhz.mjs → index-5ycb9e9q.mjs} +2 -4
  184. package/dist/esm/{index-5t2dwxsk.mjs → index-890dd9b3.mjs} +259 -21
  185. package/dist/esm/{index-ac5550e7.mjs → index-8nt6a0mw.mjs} +3 -3
  186. package/dist/esm/{index-614tdz2q.mjs → index-9q9w8v9p.mjs} +3 -3
  187. package/dist/esm/{index-s7qa3xbw.mjs → index-c2wabcdt.mjs} +6 -6
  188. package/dist/esm/{index-r1gr3j3a.mjs → index-dfy1t576.mjs} +50 -1
  189. package/dist/esm/{index-21hxsfaa.mjs → index-dh3zk2hv.mjs} +6 -25
  190. package/dist/esm/{index-4zen9prq.mjs → index-dpyss74p.mjs} +6563 -5485
  191. package/dist/esm/{index-9x6e1dq0.mjs → index-hqxc6tzp.mjs} +40 -6
  192. package/dist/esm/{index-9xxg6218.mjs → index-qve7mdfp.mjs} +19 -1
  193. package/dist/esm/{index-e855w59j.mjs → index-s6qya2gg.mjs} +3 -5
  194. package/dist/esm/index-t7tbt980.mjs +103 -0
  195. package/dist/esm/{index-r0ejh5sy.mjs → index-t7xnxdf8.mjs} +44 -26
  196. package/dist/esm/index-wqc43mw0.mjs +158 -0
  197. package/dist/esm/{index-ppspzgn9.mjs → index-x6r9bn12.mjs} +4026 -4761
  198. package/dist/esm/{index-vxwg66ar.mjs → index-xac20sv4.mjs} +44 -57
  199. package/dist/esm/index.mjs +4 -5
  200. package/dist/esm/internals.mjs +13 -13
  201. package/dist/esm/previewEntry.mjs +18 -15
  202. package/dist/esm/renderEntry.mjs +5 -1
  203. package/dist/helpers/calculate-timeline.d.ts +5 -1
  204. package/dist/helpers/calculate-timeline.js +1 -1
  205. package/dist/helpers/checkerboard-background.d.ts +2 -2
  206. package/dist/helpers/colors.d.ts +132 -112
  207. package/dist/helpers/colors.js +117 -95
  208. package/dist/helpers/create-folder-tree.js +2 -1
  209. package/dist/helpers/editor-guide-selection.d.ts +1 -1
  210. package/dist/helpers/editor-ruler.js +23 -12
  211. package/dist/helpers/get-connected-compositions.d.ts +6 -1
  212. package/dist/helpers/get-connected-compositions.js +1 -1
  213. package/dist/helpers/get-sequence-double-click-action.js +1 -1
  214. package/dist/helpers/get-sequence-visible-range.d.ts +1 -1
  215. package/dist/helpers/get-sequence-visible-range.js +2 -5
  216. package/dist/helpers/get-timeline-nestedness.d.ts +1 -1
  217. package/dist/helpers/get-timeline-nestedness.js +1 -1
  218. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +1 -1
  219. package/dist/helpers/get-timeline-sequence-sort-key.js +1 -1
  220. package/dist/helpers/hoverable.js +4 -4
  221. package/dist/helpers/inject-css.js +5 -7
  222. package/dist/helpers/prism-vsc-dark-plus.d.ts +1 -1
  223. package/dist/helpers/prism-vsc-dark-plus.js +52 -51
  224. package/dist/helpers/resolve-studio-color.d.ts +1 -0
  225. package/dist/helpers/resolve-studio-color.js +11 -0
  226. package/dist/helpers/studio-css-variables.d.ts +1 -0
  227. package/dist/helpers/studio-css-variables.js +105 -0
  228. package/dist/helpers/studio-pixel-ratio.d.ts +1 -0
  229. package/dist/helpers/studio-pixel-ratio.js +7 -0
  230. package/dist/helpers/timeline-node-path-key.d.ts +1 -1
  231. package/dist/helpers/timeline-node-path-key.js +2 -2
  232. package/dist/helpers/use-runtime-values.js +2 -28
  233. package/dist/hot-middleware-client/client.js +5 -3
  234. package/dist/icons/align-center-horizontal.js +2 -1
  235. package/dist/icons/align-left.js +2 -1
  236. package/dist/icons/align-right.js +2 -1
  237. package/dist/icons/{separation.d.ts → background-removal.d.ts} +1 -1
  238. package/dist/icons/background-removal.js +9 -0
  239. package/dist/icons/wrap.d.ts +4 -0
  240. package/dist/icons/wrap.js +10 -0
  241. package/dist/previewEntry.js +2 -0
  242. package/dist/renderEntry.js +2 -0
  243. package/dist/state/modals.d.ts +15 -1
  244. package/dist/state/timeline-sequence-hover.d.ts +6 -16
  245. package/dist/state/timeline-sequence-hover.js +6 -67
  246. package/package.json +20 -19
  247. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +0 -15
  248. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +0 -31
  249. package/dist/esm/LazyModels-nh3c8h9p.mjs +0 -12
  250. package/dist/esm/LazyModels-rr5v8h5y.mjs +0 -12
  251. package/dist/esm/index-cw0pnpg5.mjs +0 -50
  252. package/dist/esm/index-k426ye99.mjs +0 -139
  253. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +0 -82
  254. package/dist/helpers/get-box-quads-polyfill-internals.js +0 -2403
  255. package/dist/helpers/get-box-quads-ponyfill.d.ts +0 -10
  256. package/dist/helpers/get-box-quads-ponyfill.js +0 -23
  257. package/dist/icons/separation.js +0 -7
  258. /package/dist/esm/{resolve-composition-component-location-qrp05g62.mjs → resolve-composition-component-location-2hgf6g0a.mjs} +0 -0
@@ -47,8 +47,11 @@ const pointer_session_1 = require("../../helpers/pointer-session");
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
+ const get_keyframed_sequence_drag_targets_1 = require("./get-keyframed-sequence-drag-targets");
50
51
  const save_sequence_prop_1 = require("./save-sequence-prop");
51
52
  const TimelineSelection_1 = require("./TimelineSelection");
53
+ const TimelineTrimTooltip_1 = require("./TimelineTrimTooltip");
54
+ const { getParentSequencePlaybackRate, sortItemsByCommitOrder } = canvas_1.CanvasInternals;
52
55
  const HANDLE_INSET = 6;
53
56
  const HANDLE_OUTSET = 8;
54
57
  const timelineSequenceEdgeDragThresholdPx = 4;
@@ -97,58 +100,9 @@ const baseStyle = {
97
100
  bottom: 0,
98
101
  // Keep the middle half of narrow layers available for moving.
99
102
  width: `calc(${HANDLE_OUTSET}px + min(${HANDLE_INSET}px, 25%))`,
100
- cursor: 'ew-resize',
101
103
  zIndex: 1,
102
104
  touchAction: 'none',
103
105
  };
104
- const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, isDescendant, }) => {
105
- var _a;
106
- const status = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath)];
107
- if (status === null || status === undefined || !status.canUpdate) {
108
- return { effectKeyframes: [], sequenceKeyframes: [] };
109
- }
110
- const sequenceSchema = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.schema;
111
- const sequenceKeyframes = sequenceSchema === undefined
112
- ? []
113
- : Object.entries(status.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed' &&
114
- (!isDescendant || propStatus.keyframeDisplayOffsetAdjustment !== null)
115
- ? [
116
- {
117
- fileName: nodePath.absolutePath,
118
- fieldKey,
119
- isDescendant,
120
- nodePath,
121
- schema: sequenceSchema,
122
- status: propStatus,
123
- },
124
- ]
125
- : []);
126
- const effectKeyframes = status.effects.flatMap((effectStatus) => {
127
- var _a;
128
- if (!effectStatus.canUpdate) {
129
- return [];
130
- }
131
- const effectSchema = (_a = sequence.effects[effectStatus.effectIndex]) === null || _a === void 0 ? void 0 : _a.schema;
132
- if (effectSchema === undefined) {
133
- return [];
134
- }
135
- return Object.entries(effectStatus.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed' &&
136
- (!isDescendant || propStatus.keyframeDisplayOffsetAdjustment !== null)
137
- ? [
138
- {
139
- effectIndex: effectStatus.effectIndex,
140
- fileName: nodePath.absolutePath,
141
- fieldKey,
142
- isDescendant,
143
- nodePath,
144
- schema: effectSchema,
145
- status: propStatus,
146
- },
147
- ]
148
- : []);
149
- });
150
- return { effectKeyframes, sequenceKeyframes };
151
- };
152
106
  const shiftKeyframedStatus = ({ status, deltaFrames, isDescendant, }) => {
153
107
  if (isDescendant) {
154
108
  const adjustment = status.keyframeDisplayOffsetAdjustment;
@@ -209,7 +163,7 @@ const getMinimumSequenceDuration = ({ sequence, sequences, }) => {
209
163
  if (!(0, exports.isTransitionSeriesSequence)(sequence)) {
210
164
  return 1;
211
165
  }
212
- const siblings = (0, canvas_1.sortItemsByCommitOrder)(sequences.filter((candidate) => candidate.parent === sequence.parent &&
166
+ const siblings = sortItemsByCommitOrder(sequences.filter((candidate) => candidate.parent === sequence.parent &&
213
167
  ((0, exports.isTransitionSeriesSequence)(candidate) ||
214
168
  isTransitionSeriesTransition(candidate))), (candidate) => candidate.timelineOrder);
215
169
  const sequenceIndex = siblings.findIndex((candidate) => candidate.id === sequence.id);
@@ -256,7 +210,7 @@ const getTrimBeforePlaybackRate = (sequence) => {
256
210
  if (componentIdentity === null ||
257
211
  componentIdentity === undefined ||
258
212
  !playbackRateComponentIdentities.has(componentIdentity)) {
259
- return 1;
213
+ return sequence.sequencePlaybackRate;
260
214
  }
261
215
  const runtimePlaybackRate = (_b = sequence.controls) === null || _b === void 0 ? void 0 : _b.runtimeValues.getSnapshot().playbackRate;
262
216
  return typeof runtimePlaybackRate === 'number' ? runtimePlaybackRate : 1;
@@ -298,7 +252,7 @@ const getTimelineSequenceLeftEdgeDragChanges = ({ targets, deltaFrames, }) => {
298
252
  initialDuration: target.initialDuration,
299
253
  initialFrom: target.initialFrom,
300
254
  initialTrimBefore: target.initialTrimBefore,
301
- deltaFrames,
255
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
302
256
  playbackRate: target.playbackRate,
303
257
  minimumDuration: target.minimumDuration,
304
258
  });
@@ -342,7 +296,7 @@ const getTimelineSequenceDurationDragChanges = ({ targets, deltaFrames, }) => {
342
296
  return targets.flatMap((target) => {
343
297
  const nextValue = (0, exports.getTimelineSequenceDurationDragValue)({
344
298
  initialDuration: target.initialDuration,
345
- deltaFrames,
299
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
346
300
  maximumDuration: target.maximumDuration,
347
301
  minimumDuration: target.minimumDuration,
348
302
  });
@@ -373,15 +327,15 @@ const getTimelineSequenceFromDragDelta = ({ deltaFrames, timelineDurationInFrame
373
327
  }
374
328
  const nextFrom = (0, exports.getTimelineSequenceFromDragValue)({
375
329
  initialFrom: target.initialFrom,
376
- deltaFrames,
330
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
377
331
  });
378
- const distancePx = Math.abs(nextFrom * pxPerFrame);
332
+ const distancePx = Math.abs((nextFrom / target.parentPlaybackRate) * pxPerFrame);
379
333
  if (distancePx > exports.timelineSequenceFromDragSnapThresholdPx ||
380
334
  (closestSnap && closestSnap.distancePx <= distancePx)) {
381
335
  continue;
382
336
  }
383
337
  closestSnap = {
384
- deltaFrames: -target.initialFrom,
338
+ deltaFrames: -target.initialFrom / target.parentPlaybackRate,
385
339
  distancePx,
386
340
  };
387
341
  }
@@ -395,7 +349,7 @@ const getTimelineSequenceFromDragChanges = ({ targets, deltaFrames, }) => {
395
349
  return targets.flatMap((target) => {
396
350
  const nextValue = (0, exports.getTimelineSequenceFromDragValue)({
397
351
  initialFrom: target.initialFrom,
398
- deltaFrames,
352
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
399
353
  });
400
354
  if (nextValue === target.initialFrom) {
401
355
  return [];
@@ -423,10 +377,10 @@ const getTimelineSequenceFromDragKeyframeMoves = ({ targets, deltaFrames, }) =>
423
377
  nodePath: keyframeTarget.nodePath,
424
378
  fieldKey: keyframeTarget.fieldKey,
425
379
  fromFrame: keyframe.frame,
426
- toFrame: keyframe.frame + deltaFrames,
380
+ toFrame: keyframe.frame + deltaFrames * keyframeTarget.parentPlaybackRate,
427
381
  schema: keyframeTarget.schema,
428
382
  keyframeDisplayOffsetAdjustmentDelta: keyframeTarget.isDescendant
429
- ? -deltaFrames
383
+ ? -deltaFrames * keyframeTarget.parentPlaybackRate
430
384
  : undefined,
431
385
  })))),
432
386
  effectKeyframes: targets.flatMap((target) => target.effectKeyframes.flatMap((keyframeTarget) => keyframeTarget.status.keyframes.map((keyframe) => ({
@@ -435,10 +389,10 @@ const getTimelineSequenceFromDragKeyframeMoves = ({ targets, deltaFrames, }) =>
435
389
  effectIndex: keyframeTarget.effectIndex,
436
390
  fieldKey: keyframeTarget.fieldKey,
437
391
  fromFrame: keyframe.frame,
438
- toFrame: keyframe.frame + deltaFrames,
392
+ toFrame: keyframe.frame + deltaFrames * keyframeTarget.parentPlaybackRate,
439
393
  schema: keyframeTarget.schema,
440
394
  keyframeDisplayOffsetAdjustmentDelta: keyframeTarget.isDescendant
441
- ? -deltaFrames
395
+ ? -deltaFrames * keyframeTarget.parentPlaybackRate
442
396
  : undefined,
443
397
  })))),
444
398
  };
@@ -455,7 +409,7 @@ const findSequenceTrack = ({ tracks, nodePathInfo, }) => {
455
409
  };
456
410
  const getTimelineSequenceDurationDragTargets = ({ draggedNodePathInfo, draggedSequenceMediaDurationDragLimits, selectedSequenceMediaDurationDragLimits, selectedItems, sequences, overrideIdsToNodePaths, propStatuses, timelineDurationInFrames, }) => {
457
411
  var _a;
458
- var _b, _c, _d;
412
+ var _b;
459
413
  const draggedSelectionKey = (0, TimelineSelection_1.getTimelineSequenceSelectionKey)(draggedNodePathInfo);
460
414
  const selectedSequenceItems = selectedItems.filter((item) => item.type === 'sequence');
461
415
  const draggedItemIsSelected = selectedSequenceItems.some((item) => (0, TimelineSelection_1.getTimelineSequenceSelectionKey)(item.nodePathInfo) ===
@@ -505,12 +459,18 @@ const getTimelineSequenceDurationDragTargets = ({ draggedNodePathInfo, draggedSe
505
459
  return null;
506
460
  }
507
461
  const minimumDuration = Math.max(1 - originalSequence.from, getMinimumSequenceDuration({ sequence: originalSequence, sequences }));
508
- const initialDuration = (_c = mediaDurationDragLimits === null || mediaDurationDragLimits === void 0 ? void 0 : mediaDurationDragLimits.initialDuration) !== null && _c !== void 0 ? _c : originalSequence.duration;
509
- const constrainedMaximumDuration = Math.min((_d = mediaDurationDragLimits === null || mediaDurationDragLimits === void 0 ? void 0 : mediaDurationDragLimits.maximumDuration) !== null && _d !== void 0 ? _d : Infinity, timelineDurationInFrames - track.cascadedStart);
462
+ const initialDuration = mediaDurationDragLimits
463
+ ? mediaDurationDragLimits.initialDuration * track.keyframePlaybackRate
464
+ : originalSequence.duration;
465
+ const constrainedMaximumDuration = Math.min(mediaDurationDragLimits
466
+ ? mediaDurationDragLimits.maximumDuration * track.keyframePlaybackRate
467
+ : Infinity, (timelineDurationInFrames - track.cascadedStart) *
468
+ track.keyframePlaybackRate);
510
469
  const maximumDuration = isMedia
511
470
  ? Math.max(minimumDuration, initialDuration, constrainedMaximumDuration)
512
471
  : Math.max(minimumDuration, constrainedMaximumDuration);
513
472
  targets.set(key, {
473
+ parentPlaybackRate: getParentSequencePlaybackRate(originalSequence, sequences),
514
474
  fileName: nodePath.absolutePath,
515
475
  initialDuration,
516
476
  maximumDuration,
@@ -565,6 +525,7 @@ const getTimelineSequenceLeftEdgeDragTargets = ({ draggedNodePathInfo, selectedI
565
525
  const key = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath);
566
526
  if (!targets.has(key)) {
567
527
  targets.set(key, {
528
+ parentPlaybackRate: getParentSequencePlaybackRate(originalSequence, sequences),
568
529
  fileName: nodePath.absolutePath,
569
530
  initialDuration: originalSequence.duration,
570
531
  initialFrom: positionField === 'from' ? originalSequence.from : 0,
@@ -669,9 +630,10 @@ const getTimelineSequenceFromDragTargets = ({ draggedNodePathInfo, selectedItems
669
630
  }
670
631
  includedKeyframeNodePaths.add(descendantNodePathKey);
671
632
  return [
672
- getKeyframedSequenceDragTargets({
633
+ (0, get_keyframed_sequence_drag_targets_1.getKeyframedSequenceDragTargets)({
673
634
  nodePath: descendantNodePath,
674
635
  sequence,
636
+ sequences,
675
637
  propStatuses,
676
638
  isDescendant: sequence.id !== originalSequence.id,
677
639
  }),
@@ -680,8 +642,10 @@ const getTimelineSequenceFromDragTargets = ({ draggedNodePathInfo, selectedItems
680
642
  const effectKeyframes = descendantKeyframes.flatMap((descendant) => descendant.effectKeyframes);
681
643
  const sequenceKeyframes = descendantKeyframes.flatMap((descendant) => descendant.sequenceKeyframes);
682
644
  targets.set(key, {
645
+ parentPlaybackRate: getParentSequencePlaybackRate(originalSequence, sequences),
683
646
  canSnapToTimelineStart: originalSequence.parent === null,
684
- minimumDeltaFrames: 1 - originalSequence.duration - originalSequence.from,
647
+ minimumDeltaFrames: (1 - originalSequence.duration - originalSequence.from) /
648
+ getParentSequencePlaybackRate(originalSequence, sequences),
685
649
  initialTimelineStart,
686
650
  effectKeyframes,
687
651
  fileName: nodePath.absolutePath,
@@ -721,17 +685,19 @@ const clearFromDragOverrides = ({ clearDragOverrides, clearEffectDragOverrides,
721
685
  }
722
686
  }
723
687
  };
724
- const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, timelineDurationInFrames, onDragEnd, onSelect, selected, }) => {
688
+ const TimelineSequenceLeftEdgeDragHandleInner = ({ cursor, nodePathInfo, windowWidth, timelineDurationInFrames, initialEdgeFrame, fps, onDragEnd, onSelect, selected, }) => {
725
689
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
726
690
  const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
727
691
  const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
728
692
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
729
693
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
730
694
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
695
+ const [trimTooltip, setTrimTooltip] = (0, react_1.useState)(null);
731
696
  const stopPointerSessionRef = (0, react_1.useRef)(null);
732
697
  const dragStateRef = (0, react_1.useRef)(null);
733
698
  const latestRef = (0, react_1.useRef)({
734
699
  nodePathInfo,
700
+ initialEdgeFrame,
735
701
  setPropStatuses,
736
702
  setDragOverrides,
737
703
  clearDragOverrides,
@@ -742,6 +708,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
742
708
  });
743
709
  latestRef.current = {
744
710
  nodePathInfo,
711
+ initialEdgeFrame,
745
712
  setPropStatuses,
746
713
  setDragOverrides,
747
714
  clearDragOverrides,
@@ -756,6 +723,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
756
723
  return;
757
724
  }
758
725
  dragStateRef.current = null;
726
+ setTrimTooltip(null);
759
727
  latestRef.current.onDragEnd(dragState.didMove);
760
728
  document.body.style.userSelect = '';
761
729
  document.body.style.webkitUserSelect = '';
@@ -833,6 +801,11 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
833
801
  propStatuses: propStatusesRef.current,
834
802
  })) !== null && _b !== void 0 ? _b : [])
835
803
  : [];
804
+ const draggedKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(latestNodePathInfo.sequenceSubscriptionKey);
805
+ const draggedTarget = targets.find((target) => (0, studio_shared_1.stringifySequenceSubscriptionKey)(target.nodePath) === draggedKey);
806
+ const handleRect = e.currentTarget.getBoundingClientRect();
807
+ const initialEdgeClientY = handleRect.top;
808
+ const initialTimelineEdge = latestRef.current.initialEdgeFrame;
836
809
  (_a = stopPointerSessionRef.current) === null || _a === void 0 ? void 0 : _a.call(stopPointerSessionRef);
837
810
  dragStateRef.current = {
838
811
  initialClientX: e.clientX,
@@ -845,7 +818,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
845
818
  };
846
819
  document.body.style.userSelect = 'none';
847
820
  document.body.style.webkitUserSelect = 'none';
848
- (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
821
+ (0, ForceSpecificCursor_1.forceSpecificCursor)(cursor);
849
822
  const onMove = (pointerEvent) => {
850
823
  const dragState = dragStateRef.current;
851
824
  if (!dragState || pointerEvent.pointerId !== dragState.pointerId) {
@@ -866,7 +839,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
866
839
  initialDuration: target.initialDuration,
867
840
  initialFrom: target.initialFrom,
868
841
  initialTrimBefore: target.initialTrimBefore,
869
- deltaFrames,
842
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
870
843
  playbackRate: target.playbackRate,
871
844
  minimumDuration: target.minimumDuration,
872
845
  });
@@ -876,6 +849,24 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
876
849
  latestRef.current.setDragOverrides(target.nodePath, 'durationInFrames', remotion_1.Internals.makeStaticDragOverride(nextValues.durationInFrames));
877
850
  latestRef.current.setDragOverrides(target.nodePath, 'trimBefore', remotion_1.Internals.makeStaticDragOverride(nextValues.trimBefore));
878
851
  }
852
+ if (dragState.didMove && draggedTarget) {
853
+ const values = (0, exports.getTimelineSequenceLeftEdgeDragValues)({
854
+ initialDuration: draggedTarget.initialDuration,
855
+ initialFrom: draggedTarget.initialFrom,
856
+ initialTrimBefore: draggedTarget.initialTrimBefore,
857
+ deltaFrames,
858
+ playbackRate: draggedTarget.playbackRate,
859
+ minimumDuration: draggedTarget.minimumDuration,
860
+ });
861
+ const appliedDelta = values.from - draggedTarget.initialFrom;
862
+ const edgeDelta = draggedTarget.positionField === null ? 0 : appliedDelta;
863
+ setTrimTooltip({
864
+ deltaFrames: appliedDelta,
865
+ edgeFrame: initialTimelineEdge + edgeDelta,
866
+ x: pointerEvent.clientX,
867
+ y: initialEdgeClientY,
868
+ });
869
+ }
879
870
  };
880
871
  const onUp = (pointerEvent) => {
881
872
  const dragState = dragStateRef.current;
@@ -912,6 +903,7 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
912
903
  });
913
904
  }, [
914
905
  currentSelection,
906
+ cursor,
915
907
  finishDrag,
916
908
  propStatusesRef,
917
909
  selected,
@@ -929,9 +921,11 @@ const TimelineSequenceLeftEdgeDragHandleInner = ({ nodePathInfo, windowWidth, ti
929
921
  const style = {
930
922
  ...baseStyle,
931
923
  left: -HANDLE_OUTSET,
924
+ cursor,
932
925
  background: colors_1.TRANSPARENT,
933
926
  };
934
- return (jsx_runtime_1.jsx("div", { role: "separator", "aria-orientation": "vertical", title: "Drag to trim start", style: style, onPointerDown: onPointerDown }));
927
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
928
+ jsx_runtime_1.jsx("div", { role: "separator", "aria-orientation": "vertical", title: "Drag to trim start", style: style, onPointerDown: onPointerDown }), trimTooltip === null ? null : (jsx_runtime_1.jsx(TimelineTrimTooltip_1.TimelineTrimTooltip, { state: trimTooltip, fps: fps }))] }));
935
929
  };
936
930
  exports.TimelineSequenceLeftEdgeDragHandle = react_1.default.memo(TimelineSequenceLeftEdgeDragHandleInner);
937
931
  const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurationInFrames, onDragEnd, }) => {
@@ -1092,7 +1086,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
1092
1086
  for (const target of dragState.targets) {
1093
1087
  const nextFrom = (0, exports.getTimelineSequenceFromDragValue)({
1094
1088
  initialFrom: target.initialFrom,
1095
- deltaFrames,
1089
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
1096
1090
  });
1097
1091
  latestRef.current.setDragOverrides(target.nodePath, 'from', remotion_1.Internals.makeStaticDragOverride(nextFrom));
1098
1092
  for (const keyframeTarget of target.sequenceKeyframes) {
@@ -1100,7 +1094,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
1100
1094
  type: 'keyframed',
1101
1095
  status: shiftKeyframedStatus({
1102
1096
  status: keyframeTarget.status,
1103
- deltaFrames,
1097
+ deltaFrames: deltaFrames * keyframeTarget.parentPlaybackRate,
1104
1098
  isDescendant: keyframeTarget.isDescendant,
1105
1099
  }),
1106
1100
  });
@@ -1110,7 +1104,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
1110
1104
  type: 'keyframed',
1111
1105
  status: shiftKeyframedStatus({
1112
1106
  status: keyframeTarget.status,
1113
- deltaFrames,
1107
+ deltaFrames: deltaFrames * keyframeTarget.parentPlaybackRate,
1114
1108
  isDescendant: keyframeTarget.isDescendant,
1115
1109
  }),
1116
1110
  });
@@ -1142,7 +1136,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
1142
1136
  };
1143
1137
  };
1144
1138
  exports.useTimelineSequenceFromDrag = useTimelineSequenceFromDrag;
1145
- const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationDragLimits, windowWidth, timelineDurationInFrames, onDragEnd, onSelect, selected, }) => {
1139
+ const TimelineSequenceRightEdgeDragHandleInner = ({ cursor, nodePathInfo, mediaDurationDragLimits, windowWidth, timelineDurationInFrames, initialEdgeFrame, fps, onDragEnd, onSelect, selected, }) => {
1146
1140
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
1147
1141
  const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
1148
1142
  const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
@@ -1150,12 +1144,14 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1150
1144
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
1151
1145
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
1152
1146
  const mediaDurationDragLimitsRegistry = (0, react_1.useContext)(exports.TimelineSequenceMediaDurationDragLimitsContext);
1147
+ const [trimTooltip, setTrimTooltip] = (0, react_1.useState)(null);
1153
1148
  const stopPointerSessionRef = (0, react_1.useRef)(null);
1154
1149
  const dragStateRef = (0, react_1.useRef)(null);
1155
1150
  // Keep latest props/setters available to window listeners installed once at pointerdown.
1156
1151
  const latestRef = (0, react_1.useRef)({
1157
1152
  nodePathInfo,
1158
1153
  mediaDurationDragLimits,
1154
+ initialEdgeFrame,
1159
1155
  setPropStatuses,
1160
1156
  setDragOverrides,
1161
1157
  clearDragOverrides,
@@ -1167,6 +1163,7 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1167
1163
  latestRef.current = {
1168
1164
  nodePathInfo,
1169
1165
  mediaDurationDragLimits,
1166
+ initialEdgeFrame,
1170
1167
  setPropStatuses,
1171
1168
  setDragOverrides,
1172
1169
  clearDragOverrides,
@@ -1181,6 +1178,7 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1181
1178
  return;
1182
1179
  }
1183
1180
  dragStateRef.current = null;
1181
+ setTrimTooltip(null);
1184
1182
  latestRef.current.onDragEnd(dragState.didMove);
1185
1183
  document.body.style.userSelect = '';
1186
1184
  document.body.style.webkitUserSelect = '';
@@ -1259,6 +1257,11 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1259
1257
  timelineDurationInFrames,
1260
1258
  })) !== null && _c !== void 0 ? _c : [])
1261
1259
  : [];
1260
+ const draggedKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(latestNodePathInfo.sequenceSubscriptionKey);
1261
+ const draggedTarget = targets.find((target) => (0, studio_shared_1.stringifySequenceSubscriptionKey)(target.nodePath) === draggedKey);
1262
+ const handleRect = e.currentTarget.getBoundingClientRect();
1263
+ const initialEdgeClientY = handleRect.top;
1264
+ const initialTimelineEdge = latestRef.current.initialEdgeFrame;
1262
1265
  (_a = stopPointerSessionRef.current) === null || _a === void 0 ? void 0 : _a.call(stopPointerSessionRef);
1263
1266
  dragStateRef.current = {
1264
1267
  initialClientX: e.clientX,
@@ -1271,7 +1274,7 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1271
1274
  };
1272
1275
  document.body.style.userSelect = 'none';
1273
1276
  document.body.style.webkitUserSelect = 'none';
1274
- (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
1277
+ (0, ForceSpecificCursor_1.forceSpecificCursor)(cursor);
1275
1278
  const onMove = (pointerEvent) => {
1276
1279
  const dragState = dragStateRef.current;
1277
1280
  if (!dragState || pointerEvent.pointerId !== dragState.pointerId) {
@@ -1290,12 +1293,27 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1290
1293
  for (const target of dragState.targets) {
1291
1294
  const previewValue = (0, exports.getTimelineSequenceDurationDragValue)({
1292
1295
  initialDuration: target.initialDuration,
1293
- deltaFrames,
1296
+ deltaFrames: deltaFrames * target.parentPlaybackRate,
1294
1297
  maximumDuration: target.maximumDuration,
1295
1298
  minimumDuration: target.minimumDuration,
1296
1299
  });
1297
1300
  latestRef.current.setDragOverrides(target.nodePath, 'durationInFrames', remotion_1.Internals.makeStaticDragOverride(previewValue));
1298
1301
  }
1302
+ if (dragState.didMove && draggedTarget) {
1303
+ const previewValue = (0, exports.getTimelineSequenceDurationDragValue)({
1304
+ initialDuration: draggedTarget.initialDuration,
1305
+ deltaFrames,
1306
+ maximumDuration: draggedTarget.maximumDuration,
1307
+ minimumDuration: draggedTarget.minimumDuration,
1308
+ });
1309
+ const appliedDelta = previewValue - draggedTarget.initialDuration;
1310
+ setTrimTooltip({
1311
+ deltaFrames: appliedDelta,
1312
+ edgeFrame: initialTimelineEdge + appliedDelta,
1313
+ x: pointerEvent.clientX,
1314
+ y: initialEdgeClientY,
1315
+ });
1316
+ }
1299
1317
  };
1300
1318
  const onUp = (pointerEvent) => {
1301
1319
  const dragState = dragStateRef.current;
@@ -1332,6 +1350,7 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1332
1350
  });
1333
1351
  }, [
1334
1352
  currentSelection,
1353
+ cursor,
1335
1354
  finishDrag,
1336
1355
  mediaDurationDragLimitsRegistry,
1337
1356
  propStatusesRef,
@@ -1350,8 +1369,10 @@ const TimelineSequenceRightEdgeDragHandleInner = ({ nodePathInfo, mediaDurationD
1350
1369
  const style = {
1351
1370
  ...baseStyle,
1352
1371
  right: -HANDLE_OUTSET,
1372
+ cursor,
1353
1373
  background: colors_1.TRANSPARENT,
1354
1374
  };
1355
- return (jsx_runtime_1.jsx("div", { role: "separator", "aria-orientation": "vertical", title: "Drag to change duration", style: style, onPointerDown: onPointerDown }));
1375
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
1376
+ jsx_runtime_1.jsx("div", { role: "separator", "aria-orientation": "vertical", title: "Drag to change duration", style: style, onPointerDown: onPointerDown }), trimTooltip === null ? null : (jsx_runtime_1.jsx(TimelineTrimTooltip_1.TimelineTrimTooltip, { state: trimTooltip, fps: fps }))] }));
1356
1377
  };
1357
1378
  exports.TimelineSequenceRightEdgeDragHandle = react_1.default.memo(TimelineSequenceRightEdgeDragHandleInner);
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineTextContentField = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const paths_1 = require("@remotion/paths");
5
6
  const react_1 = require("react");
6
7
  const RemTextarea_1 = require("../NewComposition/RemTextarea");
7
8
  const focus_inspector_field_1 = require("./focus-inspector-field");
@@ -16,9 +17,22 @@ const textAreaStyle = {
16
17
  fieldSizing: 'content',
17
18
  },
18
19
  };
20
+ const isValidPathData = (value) => {
21
+ if (value.trim() === '') {
22
+ return true;
23
+ }
24
+ try {
25
+ (0, paths_1.parsePath)(value);
26
+ return true;
27
+ }
28
+ catch (_a) {
29
+ return false;
30
+ }
31
+ };
19
32
  const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd, onDragValueChange, onSave, propStatus, }) => {
20
33
  var _a;
21
34
  const inputRef = (0, react_1.useRef)(null);
35
+ const [valid, setValid] = (0, react_1.useState)(true);
22
36
  const currentValue = String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '');
23
37
  const draftRef = (0, react_1.useRef)({
24
38
  dirty: false,
@@ -46,6 +60,10 @@ const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd,
46
60
  return false;
47
61
  }
48
62
  const value = (_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : draftRef.current.value;
63
+ if (field.typeName === 'svg-path' && !isValidPathData(value)) {
64
+ latestRef.current.onDragEnd();
65
+ return false;
66
+ }
49
67
  const savedValue = String((_c = latestRef.current.codeValue) !== null && _c !== void 0 ? _c : '');
50
68
  draftRef.current = {
51
69
  dirty: false,
@@ -64,7 +82,7 @@ const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd,
64
82
  })
65
83
  .catch(() => undefined);
66
84
  return true;
67
- }, []);
85
+ }, [field.typeName]);
68
86
  const setInputRef = (0, react_1.useCallback)((element) => {
69
87
  if (element === null && inputRef.current !== null) {
70
88
  commitPending();
@@ -87,8 +105,12 @@ const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd,
87
105
  dirty: true,
88
106
  value,
89
107
  };
90
- latestRef.current.onDragValueChange(value);
91
- }, []);
108
+ const nextValid = field.typeName !== 'svg-path' || isValidPathData(value);
109
+ setValid(nextValid);
110
+ if (nextValid) {
111
+ latestRef.current.onDragValueChange(value);
112
+ }
113
+ }, [field.typeName]);
92
114
  const onKeyDownCapture = (0, react_1.useCallback)((event) => {
93
115
  var _a;
94
116
  if (event.key === 'Escape') {
@@ -98,10 +120,11 @@ const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd,
98
120
  value: savedValue,
99
121
  };
100
122
  event.currentTarget.value = savedValue;
123
+ setValid(true);
101
124
  latestRef.current.onDragEnd();
102
125
  event.currentTarget.blur();
103
126
  }
104
127
  }, []);
105
- return (jsx_runtime_1.jsx(RemTextarea_1.RemTextarea, { ref: setInputRef, status: "ok", small: true, defaultValue: currentValue, onBlur: commitPending, onChange: onChange, onDoubleClick: (event) => event.stopPropagation(), onKeyDownCapture: onKeyDownCapture, style: textAreaStyle }, String((_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : '')));
128
+ return (jsx_runtime_1.jsx(RemTextarea_1.RemTextarea, { ref: setInputRef, status: valid ? 'ok' : 'error', "aria-invalid": !valid, small: true, defaultValue: currentValue, onBlur: commitPending, onChange: onChange, onDoubleClick: (event) => event.stopPropagation(), onKeyDownCapture: onKeyDownCapture, style: textAreaStyle }, String((_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : '')));
106
129
  };
107
130
  exports.TimelineTextContentField = TimelineTextContentField;
@@ -38,6 +38,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
40
40
  const colors_1 = require("../../helpers/colors");
41
+ const resolve_studio_color_1 = require("../../helpers/resolve-studio-color");
42
+ const studio_pixel_ratio_1 = require("../../helpers/studio-pixel-ratio");
41
43
  const timeline_layout_1 = require("../../helpers/timeline-layout");
42
44
  const render_frame_1 = require("../../state/render-frame");
43
45
  const TimeValue_1 = require("../TimeValue");
@@ -215,8 +217,11 @@ const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, duratio
215
217
  (frameInterval * fps),
216
218
  });
217
219
  const draw = () => {
220
+ const computedStyle = getComputedStyle(canvas);
221
+ const tickColor = (0, resolve_studio_color_1.resolveStudioColor)(colors_1.WHITE_ALPHA_15, computedStyle);
222
+ const labelColor = (0, resolve_studio_color_1.resolveStudioColor)(colors_1.LIGHT_TEXT, computedStyle);
218
223
  const { clientWidth: width, scrollLeft } = scrollable;
219
- const pixelRatio = window.devicePixelRatio;
224
+ const pixelRatio = (0, studio_pixel_ratio_1.getStudioPixelRatio)();
220
225
  const canvasWidth = Math.ceil(width * pixelRatio);
221
226
  const canvasHeight = exports.TIMELINE_TIME_INDICATOR_HEIGHT * pixelRatio;
222
227
  if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {
@@ -228,7 +233,7 @@ const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, duratio
228
233
  context.resetTransform();
229
234
  context.clearRect(0, 0, canvas.width, canvas.height);
230
235
  context.scale(pixelRatio, pixelRatio);
231
- context.fillStyle = colors_1.WHITE_ALPHA_15;
236
+ context.fillStyle = tickColor;
232
237
  const firstFrame = Math.max(0, Math.floor((scrollLeft - timeline_layout_1.TIMELINE_PADDING) / frameInterval));
233
238
  const lastFrame = Math.min(durationInFrames - 1, Math.ceil((scrollLeft + width - timeline_layout_1.TIMELINE_PADDING) / frameInterval));
234
239
  const xForFrame = (frame) => Math.round(frameInterval * frame + timeline_layout_1.TIMELINE_PADDING - scrollLeft) + 0.5;
@@ -243,11 +248,11 @@ const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, duratio
243
248
  const frame = second * fps;
244
249
  drawTick(frame, 15);
245
250
  if (second > 0) {
246
- context.fillStyle = colors_1.LIGHT_TEXT;
247
- context.font = `${TICK_LABEL_FONT_SIZE}px ${getComputedStyle(canvas).fontFamily}`;
251
+ context.fillStyle = labelColor;
252
+ context.font = `${TICK_LABEL_FONT_SIZE}px ${computedStyle.fontFamily}`;
248
253
  context.textBaseline = 'top';
249
254
  context.fillText(showFrames ? `${Math.round(frame)}f` : (0, render_frame_1.renderFrame)(frame, fps), xForFrame(frame) + TICK_LABEL_MARGIN_LEFT, 7);
250
- context.fillStyle = colors_1.WHITE_ALPHA_15;
255
+ context.fillStyle = tickColor;
251
256
  }
252
257
  }
253
258
  const { minorTickEvery, mediumTickEvery } = tickScale;
@@ -66,6 +66,6 @@ const TimelineTrackUnmemoized = ({ track }) => {
66
66
  getIsExpanded(track.nodePathInfo);
67
67
  return (jsx_runtime_1.jsxs("div", { onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: [
68
68
  jsx_runtime_1.jsxs("div", { style: layerStyle, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence, cascadedStart: track.cascadedStart, localStart: track.localStart, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : emptyConnectedCompositions, nodePathInfo: track.nodePathInfo, sequenceFrameOffset: track.sequenceFrameOffset })
69
- ] }), showExpandedKeyframes && track.nodePathInfo ? (jsx_runtime_1.jsx(TimelineExpandedTrackKeyframes_1.TimelineExpandedTrackKeyframes, { sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset })) : null] }));
69
+ ] }), showExpandedKeyframes && track.nodePathInfo ? (jsx_runtime_1.jsx(TimelineExpandedTrackKeyframes_1.TimelineExpandedTrackKeyframes, { sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, keyframePlaybackRate: track.keyframePlaybackRate })) : null] }));
70
70
  };
71
71
  exports.TimelineTrack = react_1.default.memo(TimelineTrackUnmemoized);
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export type TimelineTrimTooltipState = {
3
+ readonly deltaFrames: number;
4
+ readonly edgeFrame: number;
5
+ readonly x: number;
6
+ readonly y: number;
7
+ };
8
+ export declare const TimelineTrimTooltip: React.FC<{
9
+ readonly state: TimelineTrimTooltipState;
10
+ readonly fps: number;
11
+ }>;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineTrimTooltip = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const react_dom_1 = require("react-dom");
7
+ const colors_1 = require("../../helpers/colors");
8
+ const render_frame_1 = require("../../state/render-frame");
9
+ const TimelineTickFormatProvider_1 = require("./TimelineTickFormatProvider");
10
+ const tooltip = {
11
+ backgroundColor: colors_1.BLACK_ALPHA_85,
12
+ borderRadius: 2,
13
+ boxSizing: 'border-box',
14
+ color: colors_1.WHITE,
15
+ fontSize: 11,
16
+ fontVariantNumeric: 'tabular-nums',
17
+ lineHeight: '14px',
18
+ padding: '4px 7px',
19
+ pointerEvents: 'none',
20
+ position: 'fixed',
21
+ textAlign: 'right',
22
+ whiteSpace: 'nowrap',
23
+ zIndex: 2147483647,
24
+ };
25
+ const TimelineTrimTooltip = ({ state, fps }) => {
26
+ const { showFrames } = (0, react_1.useContext)(TimelineTickFormatProvider_1.TimelineTickFormatContext);
27
+ const delta = Math.round(state.deltaFrames);
28
+ const edge = Math.max(0, Math.round(state.edgeFrame));
29
+ const format = (frame) => showFrames ? `${frame}f` : (0, render_frame_1.renderFrame)(frame, fps);
30
+ const deltaLabel = delta === 0
31
+ ? format(0)
32
+ : `${delta < 0 ? '−' : '+'}${format(Math.abs(delta))}`;
33
+ const edgeLabel = format(edge);
34
+ const tooltipWidth = Math.max(82, Math.ceil(Math.max(deltaLabel.length, edgeLabel.length) * 7 + 14));
35
+ const left = Math.max(8, Math.min(state.x - tooltipWidth / 2, window.innerWidth - tooltipWidth - 8));
36
+ const top = Math.max(8, Math.min(state.y - 40, window.innerHeight - 44));
37
+ return (0, react_dom_1.createPortal)(jsx_runtime_1.jsxs("div", { "aria-hidden": "true", style: { ...tooltip, left, top, width: tooltipWidth }, "data-remotion-timeline-trim-tooltip": "true", children: [
38
+ jsx_runtime_1.jsx("div", { children: deltaLabel }), jsx_runtime_1.jsx("div", { style: { color: colors_1.LIGHT_TEXT }, children: edgeLabel })
39
+ ] }), document.body);
40
+ };
41
+ exports.TimelineTrimTooltip = TimelineTrimTooltip;