@remotion/studio 4.0.512 → 4.0.514

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 (208) hide show
  1. package/dist/Studio.js +2 -1
  2. package/dist/components/AskAiModal.js +1 -1
  3. package/dist/components/AssetSelector.js +2 -0
  4. package/dist/components/AssetSelectorItem.js +1 -2
  5. package/dist/components/AudioWaveform.d.ts +3 -0
  6. package/dist/components/AudioWaveform.js +55 -67
  7. package/dist/components/Canvas.js +40 -5
  8. package/dist/components/CanvasOrLoading.js +5 -0
  9. package/dist/components/CompositionSelector.js +2 -0
  10. package/dist/components/CompositionSelectorItem.js +14 -1
  11. package/dist/components/ConfigureDefaultEditorModal.js +17 -11
  12. package/dist/components/Editor.js +16 -1
  13. package/dist/components/ElementInstallConfirmation.d.ts +1 -0
  14. package/dist/components/ElementInstallConfirmation.js +4 -2
  15. package/dist/components/FixComputedValueModal.d.ts +9 -0
  16. package/dist/components/FixComputedValueModal.js +217 -0
  17. package/dist/components/InitialCompositionLoader.js +19 -0
  18. package/dist/components/InlineDropdown.js +4 -4
  19. package/dist/components/InspectorInfoHeader.js +3 -3
  20. package/dist/components/InspectorOpenInEditor.js +26 -24
  21. package/dist/components/InspectorPanel/AlignmentControls.js +13 -2
  22. package/dist/components/InspectorPanel/CompositionInspector.js +11 -1
  23. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +12 -8
  24. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +13 -2
  25. package/dist/components/InspectorPanel/EasingInspector.js +12 -3
  26. package/dist/components/InspectorPanel/KeyframeInspector.js +21 -7
  27. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +1 -1
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +35 -6
  29. package/dist/components/InspectorPanel/common.d.ts +5 -5
  30. package/dist/components/InspectorPanel/common.js +8 -8
  31. package/dist/components/InspectorPanel/easing-inspector-selection.js +7 -2
  32. package/dist/components/InspectorPanel/inspector-section-collapse.d.ts +1 -0
  33. package/dist/components/InspectorPanel/styles.d.ts +1 -1
  34. package/dist/components/InspectorPanel/styles.js +4 -2
  35. package/dist/components/InspectorSourceLocation.d.ts +1 -1
  36. package/dist/components/InspectorSourceLocation.js +2 -2
  37. package/dist/components/LicenseKeyValidation.js +2 -2
  38. package/dist/components/Modals.js +2 -1
  39. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  40. package/dist/components/NewComposition/CodemodFooter.js +10 -8
  41. package/dist/components/NewComposition/DeleteComposition.js +1 -1
  42. package/dist/components/NewComposition/DeleteFolder.js +1 -1
  43. package/dist/components/NewComposition/DuplicateComposition.js +7 -2
  44. package/dist/components/NewComposition/NewComposition.js +1 -1
  45. package/dist/components/NewComposition/NewFolder.js +1 -1
  46. package/dist/components/NewComposition/RenameComposition.js +1 -1
  47. package/dist/components/NewComposition/RenameFolder.js +1 -1
  48. package/dist/components/NewComposition/duplicate-composition-api.d.ts +16 -0
  49. package/dist/components/NewComposition/duplicate-composition-api.js +16 -0
  50. package/dist/components/NoRegisterRoot.js +1 -1
  51. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +4 -3
  52. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  53. package/dist/components/QuickSwitcher/fuzzy-search.js +1 -1
  54. package/dist/components/RefreshCompositionOverlay.js +1 -1
  55. package/dist/components/RenderButton.js +6 -3
  56. package/dist/components/RenderModal/WebRenderModal.js +6 -2
  57. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +2 -0
  58. package/dist/components/RenderModal/WebRenderModalAdvanced.js +9 -2
  59. package/dist/components/RenderModal/render-modals.js +5 -1
  60. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +5 -1
  61. package/dist/components/RenderQueue/actions.js +12 -2
  62. package/dist/components/RenderQueue/client-side-render-types.d.ts +1 -0
  63. package/dist/components/RenderingSettings.d.ts +2 -0
  64. package/dist/components/RenderingSettings.js +355 -0
  65. package/dist/components/SelectedOutlineElement.js +15 -13
  66. package/dist/components/SelectedOutlineOverlay.js +30 -8
  67. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  68. package/dist/components/SelectedOutlinePolygon.js +53 -9
  69. package/dist/components/SettingsContext.d.ts +4 -1
  70. package/dist/components/SettingsContext.js +9 -2
  71. package/dist/components/SettingsModal.d.ts +1 -1
  72. package/dist/components/SettingsModal.js +10 -1
  73. package/dist/components/SettingsModalFooter.js +1 -1
  74. package/dist/components/StudioSettings.d.ts +2 -0
  75. package/dist/components/StudioSettings.js +185 -0
  76. package/dist/components/Timeline/LoopedIndicator.js +1 -1
  77. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +3 -0
  78. package/dist/components/Timeline/LoopedTimelineIndicators.js +22 -14
  79. package/dist/components/Timeline/Timeline.js +11 -9
  80. package/dist/components/Timeline/TimelineArrayField.js +1 -0
  81. package/dist/components/Timeline/TimelineAssetField.d.ts +2 -2
  82. package/dist/components/Timeline/TimelineAssetField.js +1 -1
  83. package/dist/components/Timeline/TimelineDragHandler.js +62 -76
  84. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  85. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +4 -2
  86. package/dist/components/Timeline/TimelineEffectPropItem.js +25 -14
  87. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -1
  88. package/dist/components/Timeline/TimelineExpandedRow.js +4 -4
  89. package/dist/components/Timeline/TimelineExpandedSection.js +1 -1
  90. package/dist/components/Timeline/TimelineHeightContainer.d.ts +0 -4
  91. package/dist/components/Timeline/TimelineHeightContainer.js +4 -4
  92. package/dist/components/Timeline/TimelineImageInfo.d.ts +1 -0
  93. package/dist/components/Timeline/TimelineImageInfo.js +3 -2
  94. package/dist/components/Timeline/TimelineKeyframeControls.js +31 -8
  95. package/dist/components/Timeline/TimelineKeyframedValue.js +1 -0
  96. package/dist/components/Timeline/TimelineList.d.ts +1 -5
  97. package/dist/components/Timeline/TimelineList.js +14 -9
  98. package/dist/components/Timeline/TimelinePinchZoom.js +5 -5
  99. package/dist/components/Timeline/TimelineRowChrome.d.ts +0 -2
  100. package/dist/components/Timeline/TimelineRowChrome.js +12 -5
  101. package/dist/components/Timeline/TimelineSchemaField.d.ts +7 -3
  102. package/dist/components/Timeline/TimelineSchemaField.js +71 -13
  103. package/dist/components/Timeline/TimelineScrollable.js +3 -1
  104. package/dist/components/Timeline/TimelineSelection.d.ts +5 -2
  105. package/dist/components/Timeline/TimelineSelection.js +90 -103
  106. package/dist/components/Timeline/TimelineSequence.js +59 -25
  107. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -1
  108. package/dist/components/Timeline/TimelineSequenceItem.js +15 -9
  109. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +2 -1
  110. package/dist/components/Timeline/TimelineSequencePropItem.js +14 -7
  111. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +3 -0
  112. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +128 -27
  113. package/dist/components/Timeline/TimelineSlider.js +42 -33
  114. package/dist/components/Timeline/TimelineTimeIndicators.js +90 -98
  115. package/dist/components/Timeline/TimelineTracks.d.ts +0 -2
  116. package/dist/components/Timeline/TimelineTracks.js +11 -4
  117. package/dist/components/Timeline/TimelineTransformOriginField.js +1 -1
  118. package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -4
  119. package/dist/components/Timeline/TimelineVideoInfo.js +151 -61
  120. package/dist/components/Timeline/TimelineViewport.d.ts +12 -0
  121. package/dist/components/Timeline/TimelineViewport.js +62 -0
  122. package/dist/components/Timeline/TimelineVirtualization.d.ts +22 -0
  123. package/dist/components/Timeline/TimelineVirtualization.js +144 -0
  124. package/dist/components/Timeline/TimelineZoomControls.js +16 -8
  125. package/dist/components/Timeline/call-add-keyframe.js +31 -3
  126. package/dist/components/Timeline/call-delete-keyframe.js +13 -3
  127. package/dist/components/Timeline/call-move-keyframe.d.ts +2 -1
  128. package/dist/components/Timeline/call-move-keyframe.js +81 -18
  129. package/dist/components/Timeline/call-update-keyframe-settings.js +31 -3
  130. package/dist/components/Timeline/delete-selected-keyframe.d.ts +0 -8
  131. package/dist/components/Timeline/delete-selected-keyframe.js +23 -44
  132. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +0 -8
  133. package/dist/components/Timeline/delete-selected-timeline-item.js +18 -44
  134. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +8 -3
  135. package/dist/components/Timeline/get-sequence-context-menu-items.js +10 -8
  136. package/dist/components/Timeline/get-timeline-keyframes.d.ts +5 -2
  137. package/dist/components/Timeline/get-timeline-keyframes.js +16 -10
  138. package/dist/components/Timeline/get-timeline-sequence-visible-layout.d.ts +30 -0
  139. package/dist/components/Timeline/get-timeline-sequence-visible-layout.js +61 -0
  140. package/dist/components/Timeline/keyframe-clipboard.js +9 -2
  141. package/dist/components/Timeline/split-selected-timeline-item.js +2 -2
  142. package/dist/components/Timeline/timeline-scroll-logic.d.ts +24 -0
  143. package/dist/components/Timeline/timeline-scroll-logic.js +127 -4
  144. package/dist/components/Timeline/use-open-sequence-in-apps.js +8 -8
  145. package/dist/components/Timeline/use-timeline-height.d.ts +3 -5
  146. package/dist/components/Timeline/use-timeline-height.js +16 -18
  147. package/dist/components/Timeline/use-timeline-keyframe-drag.js +14 -4
  148. package/dist/components/UpdateCheck.d.ts +2 -10
  149. package/dist/components/UpdateCheck.js +8 -2
  150. package/dist/components/VisualControls/ClickableFileName.js +13 -6
  151. package/dist/components/VisualControls/VisualControlHandle.js +8 -0
  152. package/dist/components/composition-menu-items.d.ts +6 -1
  153. package/dist/components/composition-menu-items.js +9 -6
  154. package/dist/components/delete-jsx-node-api.d.ts +2 -0
  155. package/dist/components/delete-jsx-node-api.js +12 -0
  156. package/dist/components/element-install-api.d.ts +3 -0
  157. package/dist/components/element-install-api.js +19 -0
  158. package/dist/components/folder-menu-items.d.ts +4 -1
  159. package/dist/components/folder-menu-items.js +4 -5
  160. package/dist/components/get-open-in-menu-items.d.ts +1 -1
  161. package/dist/components/get-open-in-menu-items.js +15 -13
  162. package/dist/components/import-assets.js +20 -9
  163. package/dist/components/reorder-sequence-api.d.ts +2 -0
  164. package/dist/components/reorder-sequence-api.js +12 -0
  165. package/dist/components/sequence-props-api.js +44 -3
  166. package/dist/components/split-jsx-sequence-api.d.ts +2 -0
  167. package/dist/components/split-jsx-sequence-api.js +12 -0
  168. package/dist/components/split-video-from-audio-api.d.ts +2 -0
  169. package/dist/components/split-video-from-audio-api.js +12 -0
  170. package/dist/components/use-default-editor-info.d.ts +8 -0
  171. package/dist/components/use-default-editor-info.js +25 -9
  172. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +10 -3
  173. package/dist/error-overlay/remotion-overlay/OpenInEditor.d.ts +3 -1
  174. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +6 -6
  175. package/dist/error-overlay/remotion-overlay/Overlay.js +14 -12
  176. package/dist/error-overlay/remotion-overlay/StackFrame.d.ts +2 -1
  177. package/dist/error-overlay/remotion-overlay/StackFrame.js +7 -4
  178. package/dist/esm/{chunk-s8gwjng0.js → chunk-xn2q7eem.js} +11983 -8035
  179. package/dist/esm/index.mjs +7 -5
  180. package/dist/esm/internals.mjs +11983 -8035
  181. package/dist/esm/previewEntry.mjs +13059 -9107
  182. package/dist/esm/renderEntry.mjs +2 -3
  183. package/dist/helpers/browser-studio-operations.d.ts +2 -0
  184. package/dist/helpers/browser-studio-operations.js +10 -1
  185. package/dist/helpers/get-timeline-max-zoom.d.ts +26 -0
  186. package/dist/helpers/get-timeline-max-zoom.js +45 -0
  187. package/dist/helpers/inject-css.js +2 -2
  188. package/dist/helpers/open-in-editor.d.ts +6 -4
  189. package/dist/helpers/open-in-editor.js +4 -4
  190. package/dist/helpers/render-codec-label.d.ts +1 -1
  191. package/dist/helpers/retry-payload.js +1 -0
  192. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  193. package/dist/helpers/studio-runtime-config.js +2 -3
  194. package/dist/helpers/timeline-layout.d.ts +3 -1
  195. package/dist/helpers/timeline-layout.js +6 -1
  196. package/dist/helpers/url-state.js +3 -2
  197. package/dist/helpers/use-menu-structure.js +12 -11
  198. package/dist/helpers/use-runtime-values.d.ts +2 -1
  199. package/dist/helpers/use-runtime-values.js +7 -3
  200. package/dist/icons/remotion-triangle.d.ts +2 -0
  201. package/dist/icons/remotion-triangle.js +7 -0
  202. package/dist/renderEntry.js +1 -1
  203. package/dist/state/composition-list.d.ts +13 -0
  204. package/dist/state/composition-list.js +21 -0
  205. package/dist/state/modals.d.ts +7 -1
  206. package/dist/state/timeline-zoom.d.ts +1 -2
  207. package/dist/state/timeline-zoom.js +9 -5
  208. package/package.json +14 -13
@@ -60,7 +60,7 @@ const baseStyle = {
60
60
  zIndex: 1,
61
61
  touchAction: 'none',
62
62
  };
63
- const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, }) => {
63
+ const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, isDescendant, }) => {
64
64
  var _a;
65
65
  const status = propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath)];
66
66
  if (status === null || status === undefined || !status.canUpdate) {
@@ -69,8 +69,18 @@ const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, })
69
69
  const sequenceSchema = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.schema;
70
70
  const sequenceKeyframes = sequenceSchema === undefined
71
71
  ? []
72
- : Object.entries(status.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed'
73
- ? [{ fieldKey, schema: sequenceSchema, status: propStatus }]
72
+ : Object.entries(status.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed' &&
73
+ (!isDescendant || propStatus.keyframeDisplayOffsetAdjustment !== null)
74
+ ? [
75
+ {
76
+ fileName: nodePath.absolutePath,
77
+ fieldKey,
78
+ isDescendant,
79
+ nodePath,
80
+ schema: sequenceSchema,
81
+ status: propStatus,
82
+ },
83
+ ]
74
84
  : []);
75
85
  const effectKeyframes = status.effects.flatMap((effectStatus) => {
76
86
  var _a;
@@ -81,11 +91,15 @@ const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, })
81
91
  if (effectSchema === undefined) {
82
92
  return [];
83
93
  }
84
- return Object.entries(effectStatus.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed'
94
+ return Object.entries(effectStatus.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed' &&
95
+ (!isDescendant || propStatus.keyframeDisplayOffsetAdjustment !== null)
85
96
  ? [
86
97
  {
87
98
  effectIndex: effectStatus.effectIndex,
99
+ fileName: nodePath.absolutePath,
88
100
  fieldKey,
101
+ isDescendant,
102
+ nodePath,
89
103
  schema: effectSchema,
90
104
  status: propStatus,
91
105
  },
@@ -94,7 +108,21 @@ const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, })
94
108
  });
95
109
  return { effectKeyframes, sequenceKeyframes };
96
110
  };
97
- const shiftKeyframedStatus = ({ status, deltaFrames, }) => {
111
+ const shiftKeyframedStatus = ({ status, deltaFrames, isDescendant, }) => {
112
+ if (isDescendant) {
113
+ const adjustment = status.keyframeDisplayOffsetAdjustment;
114
+ if (adjustment === null) {
115
+ throw new Error('Expected descendant keyframes to use an outer frame clock');
116
+ }
117
+ return {
118
+ ...status,
119
+ keyframeDisplayOffsetAdjustment: null,
120
+ keyframes: status.keyframes.map((keyframe) => ({
121
+ ...keyframe,
122
+ frame: keyframe.frame + adjustment,
123
+ })),
124
+ };
125
+ }
98
126
  return {
99
127
  ...status,
100
128
  keyframes: status.keyframes.map((keyframe) => ({
@@ -352,21 +380,27 @@ const getTimelineSequenceFromDragKeyframeMoves = ({ targets, deltaFrames, }) =>
352
380
  }
353
381
  return {
354
382
  sequenceKeyframes: targets.flatMap((target) => target.sequenceKeyframes.flatMap((keyframeTarget) => keyframeTarget.status.keyframes.map((keyframe) => ({
355
- fileName: target.fileName,
356
- nodePath: target.nodePath,
383
+ fileName: keyframeTarget.fileName,
384
+ nodePath: keyframeTarget.nodePath,
357
385
  fieldKey: keyframeTarget.fieldKey,
358
386
  fromFrame: keyframe.frame,
359
387
  toFrame: keyframe.frame + deltaFrames,
360
388
  schema: keyframeTarget.schema,
389
+ keyframeDisplayOffsetAdjustmentDelta: keyframeTarget.isDescendant
390
+ ? -deltaFrames
391
+ : undefined,
361
392
  })))),
362
393
  effectKeyframes: targets.flatMap((target) => target.effectKeyframes.flatMap((keyframeTarget) => keyframeTarget.status.keyframes.map((keyframe) => ({
363
- fileName: target.fileName,
364
- nodePath: target.nodePath,
394
+ fileName: keyframeTarget.fileName,
395
+ nodePath: keyframeTarget.nodePath,
365
396
  effectIndex: keyframeTarget.effectIndex,
366
397
  fieldKey: keyframeTarget.fieldKey,
367
398
  fromFrame: keyframe.frame,
368
399
  toFrame: keyframe.frame + deltaFrames,
369
400
  schema: keyframeTarget.schema,
401
+ keyframeDisplayOffsetAdjustmentDelta: keyframeTarget.isDescendant
402
+ ? -deltaFrames
403
+ : undefined,
370
404
  })))),
371
405
  };
372
406
  };
@@ -509,29 +543,86 @@ const getTimelineSequenceFromDragTargets = ({ draggedNodePathInfo, selectedItems
509
543
  ? selectedSequenceItems.map((item) => item.nodePathInfo)
510
544
  : [draggedNodePathInfo];
511
545
  const tracks = (0, calculate_timeline_1.calculateTimeline)({ sequences, overrideIdsToNodePaths });
512
- const targets = new Map();
513
- for (const nodePathInfo of targetNodePathInfos) {
546
+ const sequencesById = new Map(sequences.map((sequence) => [sequence.id, sequence]));
547
+ const selectedSequences = targetNodePathInfos.flatMap((nodePathInfo) => {
514
548
  const track = findSequenceTrack({ tracks, nodePathInfo });
515
549
  const originalSequence = track
516
- ? sequences.find((sequence) => sequence.id === track.sequence.id)
517
- : null;
518
- if (!track ||
519
- !track.nodePathInfo ||
520
- !originalSequence ||
521
- !isFromDraggableSequence(originalSequence)) {
550
+ ? sequencesById.get(track.sequence.id)
551
+ : undefined;
552
+ if (!(track === null || track === void 0 ? void 0 : track.nodePathInfo) || !originalSequence) {
553
+ return [];
554
+ }
555
+ return [
556
+ {
557
+ nodePath: track.nodePathInfo.sequenceSubscriptionKey,
558
+ originalSequence,
559
+ },
560
+ ];
561
+ });
562
+ if (selectedSequences.length !== targetNodePathInfos.length) {
563
+ return null;
564
+ }
565
+ const selectedSequenceIds = new Set(selectedSequences.map(({ originalSequence }) => originalSequence.id));
566
+ const sequencesWithoutSelectedAncestors = selectedSequences.filter(({ originalSequence }) => {
567
+ var _a;
568
+ var _b;
569
+ let parentId = originalSequence.parent;
570
+ while (parentId !== null) {
571
+ if (selectedSequenceIds.has(parentId)) {
572
+ return false;
573
+ }
574
+ parentId = (_b = (_a = sequencesById.get(parentId)) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
575
+ }
576
+ return true;
577
+ });
578
+ const targets = new Map();
579
+ const includedKeyframeNodePaths = new Set();
580
+ for (const { nodePath, originalSequence, } of sequencesWithoutSelectedAncestors) {
581
+ if (!isFromDraggableSequence(originalSequence)) {
522
582
  return null;
523
583
  }
524
- const nodePath = track.nodePathInfo.sequenceSubscriptionKey;
525
584
  if (!canUpdateFrom({ propStatuses, nodePath })) {
526
585
  return null;
527
586
  }
528
587
  const key = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath);
529
588
  if (!targets.has(key)) {
530
- const { effectKeyframes, sequenceKeyframes } = getKeyframedSequenceDragTargets({
531
- nodePath,
532
- sequence: originalSequence,
533
- propStatuses,
589
+ const descendants = sequences.filter((candidate) => {
590
+ var _a;
591
+ var _b;
592
+ let parentId = candidate.id;
593
+ while (parentId !== null) {
594
+ if (parentId === originalSequence.id) {
595
+ return true;
596
+ }
597
+ parentId = (_b = (_a = sequencesById.get(parentId)) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
598
+ }
599
+ return false;
534
600
  });
601
+ const descendantKeyframes = descendants.flatMap((sequence) => {
602
+ var _a;
603
+ const overrideId = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.overrideId;
604
+ const descendantNodePath = overrideId
605
+ ? overrideIdsToNodePaths[overrideId]
606
+ : undefined;
607
+ if (descendantNodePath === undefined) {
608
+ return [];
609
+ }
610
+ const descendantNodePathKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(descendantNodePath);
611
+ if (includedKeyframeNodePaths.has(descendantNodePathKey)) {
612
+ return [];
613
+ }
614
+ includedKeyframeNodePaths.add(descendantNodePathKey);
615
+ return [
616
+ getKeyframedSequenceDragTargets({
617
+ nodePath: descendantNodePath,
618
+ sequence,
619
+ propStatuses,
620
+ isDescendant: sequence.id !== originalSequence.id,
621
+ }),
622
+ ];
623
+ });
624
+ const effectKeyframes = descendantKeyframes.flatMap((descendant) => descendant.effectKeyframes);
625
+ const sequenceKeyframes = descendantKeyframes.flatMap((descendant) => descendant.sequenceKeyframes);
535
626
  targets.set(key, {
536
627
  canSnapToTimelineStart: originalSequence.parent === null,
537
628
  effectKeyframes,
@@ -558,9 +649,17 @@ const clearDurationDragOverrides = ({ clearDragOverrides, targets, }) => {
558
649
  const clearFromDragOverrides = ({ clearDragOverrides, clearEffectDragOverrides, targets, }) => {
559
650
  for (const target of targets) {
560
651
  clearDragOverrides(target.nodePath);
561
- const effectIndexes = new Set(target.effectKeyframes.map((keyframe) => keyframe.effectIndex));
562
- for (const effectIndex of effectIndexes) {
563
- clearEffectDragOverrides(target.nodePath, effectIndex);
652
+ for (const keyframeTarget of target.sequenceKeyframes) {
653
+ clearDragOverrides(keyframeTarget.nodePath);
654
+ }
655
+ const clearedEffects = new Set();
656
+ for (const keyframeTarget of target.effectKeyframes) {
657
+ const key = `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(keyframeTarget.nodePath)}:${keyframeTarget.effectIndex}`;
658
+ if (clearedEffects.has(key)) {
659
+ continue;
660
+ }
661
+ clearedEffects.add(key);
662
+ clearEffectDragOverrides(keyframeTarget.nodePath, keyframeTarget.effectIndex);
564
663
  }
565
664
  }
566
665
  };
@@ -916,20 +1015,22 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
916
1015
  });
917
1016
  latestRef.current.setDragOverrides(target.nodePath, 'from', remotion_1.Internals.makeStaticDragOverride(nextFrom));
918
1017
  for (const keyframeTarget of target.sequenceKeyframes) {
919
- latestRef.current.setDragOverrides(target.nodePath, keyframeTarget.fieldKey, {
1018
+ latestRef.current.setDragOverrides(keyframeTarget.nodePath, keyframeTarget.fieldKey, {
920
1019
  type: 'keyframed',
921
1020
  status: shiftKeyframedStatus({
922
1021
  status: keyframeTarget.status,
923
1022
  deltaFrames,
1023
+ isDescendant: keyframeTarget.isDescendant,
924
1024
  }),
925
1025
  });
926
1026
  }
927
1027
  for (const keyframeTarget of target.effectKeyframes) {
928
- latestRef.current.setEffectDragOverrides(target.nodePath, keyframeTarget.effectIndex, keyframeTarget.fieldKey, {
1028
+ latestRef.current.setEffectDragOverrides(keyframeTarget.nodePath, keyframeTarget.effectIndex, keyframeTarget.fieldKey, {
929
1029
  type: 'keyframed',
930
1030
  status: shiftKeyframedStatus({
931
1031
  status: keyframeTarget.status,
932
1032
  deltaFrames,
1033
+ isDescendant: keyframeTarget.isDescendant,
933
1034
  }),
934
1035
  });
935
1036
  }
@@ -11,12 +11,21 @@ const imperative_state_1 = require("./imperative-state");
11
11
  const timeline_refs_1 = require("./timeline-refs");
12
12
  const TimelineSliderHandle_1 = require("./TimelineSliderHandle");
13
13
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
14
- const container = {
14
+ const clippingContainer = {
15
15
  position: 'absolute',
16
- bottom: 0,
17
16
  top: 0,
17
+ left: 0,
18
+ width: '100%',
19
+ height: '100vh',
20
+ overflow: 'hidden',
18
21
  pointerEvents: 'none',
19
22
  };
23
+ const slider = {
24
+ position: 'absolute',
25
+ top: 0,
26
+ left: 0,
27
+ height: '100%',
28
+ };
20
29
  const PLAYHEAD_LINE_WIDTH = 1;
21
30
  const line = {
22
31
  height: '100vh',
@@ -25,9 +34,9 @@ const line = {
25
34
  backgroundColor: colors_1.TIMELINE_PLAYHEAD_COLOR,
26
35
  };
27
36
  const PLAYHEAD_CENTER_OFFSET = PLAYHEAD_LINE_WIDTH / 2;
28
- const getTimelineSliderTransform = ({ durationInFrames, frame, width, }) => {
37
+ const getTimelineSliderTransform = ({ durationInFrames, frame, scrollLeft, width, }) => {
29
38
  const left = (0, get_left_of_timeline_slider_1.getXPositionOfItemInTimelineImperatively)(frame, durationInFrames, width);
30
- return `translateX(${left - PLAYHEAD_CENTER_OFFSET}px)`;
39
+ return `translateX(${left - scrollLeft - PLAYHEAD_CENTER_OFFSET}px)`;
31
40
  };
32
41
  exports.redrawTimelineSliderFast = (0, react_1.createRef)();
33
42
  const TimelineSlider = () => {
@@ -57,14 +66,30 @@ const TimelineSliderInner = () => {
57
66
  var _a;
58
67
  const el = ref.current;
59
68
  const measuredWidth = (_a = timeline_refs_1.sliderAreaRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth;
60
- if (!el || measuredWidth === undefined || measuredWidth === 0) {
69
+ const scrollable = timeline_refs_1.scrollableRef.current;
70
+ if (!el ||
71
+ !scrollable ||
72
+ measuredWidth === undefined ||
73
+ measuredWidth === 0) {
61
74
  return;
62
75
  }
63
- el.style.transform = getTimelineSliderTransform({
64
- durationInFrames: videoConfig.durationInFrames,
65
- frame: timelinePosition,
66
- width: measuredWidth,
67
- });
76
+ const draw = (frame) => {
77
+ el.style.transform = getTimelineSliderTransform({
78
+ durationInFrames: videoConfig.durationInFrames,
79
+ frame,
80
+ scrollLeft: scrollable.scrollLeft,
81
+ width: measuredWidth,
82
+ });
83
+ };
84
+ draw(timelinePosition);
85
+ // Read the frame imperatively on scroll: during edge auto-scrolling, the
86
+ // scroll event can fire before React has committed the seek, and drawing
87
+ // with the stale `timelinePosition` closure makes the playhead flicker.
88
+ const onScroll = () => draw((0, imperative_state_1.getCurrentFrame)());
89
+ scrollable.addEventListener('scroll', onScroll);
90
+ return () => {
91
+ scrollable.removeEventListener('scroll', onScroll);
92
+ };
68
93
  }, [
69
94
  timelinePosition,
70
95
  videoConfig.durationInFrames,
@@ -74,8 +99,8 @@ const TimelineSliderInner = () => {
74
99
  (0, react_1.useImperativeHandle)(exports.redrawTimelineSliderFast, () => {
75
100
  return {
76
101
  draw: (frame, width) => {
77
- var _a;
78
- var _b;
102
+ var _a, _b;
103
+ var _c, _d;
79
104
  const { current } = ref;
80
105
  if (!current) {
81
106
  throw new Error('unexpectedly did not have ref to timelineslider');
@@ -83,29 +108,13 @@ const TimelineSliderInner = () => {
83
108
  current.style.transform = getTimelineSliderTransform({
84
109
  durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
85
110
  frame,
86
- width: (_b = width !== null && width !== void 0 ? width : (_a = timeline_refs_1.sliderAreaRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : 0,
111
+ scrollLeft: (_c = (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.scrollLeft) !== null && _c !== void 0 ? _c : 0,
112
+ width: (_d = width !== null && width !== void 0 ? width : (_b = timeline_refs_1.sliderAreaRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) !== null && _d !== void 0 ? _d : 0,
87
113
  });
88
114
  },
89
115
  };
90
116
  }, []);
91
- (0, react_1.useEffect)(() => {
92
- const currentRef = ref.current;
93
- if (!currentRef) {
94
- return;
95
- }
96
- const { current } = timeline_refs_1.timelineVerticalScroll;
97
- if (!current) {
98
- return;
99
- }
100
- const onScroll = () => {
101
- currentRef.style.top = current.scrollTop + 'px';
102
- };
103
- current.addEventListener('scroll', onScroll);
104
- return () => {
105
- current.removeEventListener('scroll', onScroll);
106
- };
107
- }, []);
108
- return (jsx_runtime_1.jsxs("div", { ref: ref, style: container, children: [
109
- jsx_runtime_1.jsx("div", { style: line }), jsx_runtime_1.jsx(TimelineSliderHandle_1.TimelineSliderHandle, {})
110
- ] }));
117
+ return (jsx_runtime_1.jsx("div", { style: clippingContainer, children: jsx_runtime_1.jsxs("div", { ref: ref, style: slider, children: [
118
+ jsx_runtime_1.jsx("div", { style: line }), jsx_runtime_1.jsx(TimelineSliderHandle_1.TimelineSliderHandle, {})
119
+ ] }) }));
111
120
  };
@@ -53,16 +53,6 @@ const container = {
53
53
  top: 0,
54
54
  borderBottom: `${timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM}px solid ${colors_1.TIMELINE_TRACK_SEPARATOR}`,
55
55
  };
56
- const tick = {
57
- width: 1,
58
- backgroundColor: colors_1.WHITE_ALPHA_15,
59
- height: 20,
60
- position: 'absolute',
61
- };
62
- const secondTick = {
63
- ...tick,
64
- height: 15,
65
- };
66
56
  const TICK_LABEL_FONT_SIZE = 12;
67
57
  const TICK_LABEL_MARGIN_LEFT = 8;
68
58
  const TICK_LABEL_MIN_GAP = 16;
@@ -70,12 +60,6 @@ const MIN_SPACING_BETWEEN_FRAME_TICKS_PX = 5;
70
60
  const MIN_SPACING_BETWEEN_TIME_TICKS_PX = 16;
71
61
  const MIN_SPACING_BETWEEN_MEDIUM_FRAME_TICKS_PX = 24;
72
62
  const MIN_SPACING_BETWEEN_MEDIUM_TIME_TICKS_PX = 48;
73
- const tickLabel = {
74
- fontSize: TICK_LABEL_FONT_SIZE,
75
- marginLeft: TICK_LABEL_MARGIN_LEFT,
76
- marginTop: 7,
77
- color: colors_1.LIGHT_TEXT,
78
- };
79
63
  const timeValue = {
80
64
  height: exports.TIMELINE_TIME_INDICATOR_HEIGHT,
81
65
  position: 'absolute',
@@ -205,103 +189,111 @@ const TimelineTimeIndicators = () => {
205
189
  };
206
190
  exports.TimelineTimeIndicators = TimelineTimeIndicators;
207
191
  const TimelineTimeIndicatorsInner = react_1.default.memo(({ windowWidth, durationInFrames, fps }) => {
208
- const ref = (0, react_1.useRef)(null);
209
- (0, react_1.useEffect)(() => {
210
- const currentRef = ref.current;
211
- if (!currentRef) {
192
+ const canvasRef = (0, react_1.useRef)(null);
193
+ (0, react_1.useLayoutEffect)(() => {
194
+ const canvas = canvasRef.current;
195
+ const scrollable = timeline_refs_1.scrollableRef.current;
196
+ if (!canvas || !scrollable) {
212
197
  return;
213
198
  }
214
- const { current } = timeline_refs_1.timelineVerticalScroll;
215
- if (!current) {
199
+ const context = canvas.getContext('2d');
200
+ if (!context) {
216
201
  return;
217
202
  }
218
- const onScroll = () => {
219
- currentRef.style.top = current.scrollTop + 'px';
220
- };
221
- current.addEventListener('scroll', onScroll);
222
- return () => {
223
- current.removeEventListener('scroll', onScroll);
224
- };
225
- }, []);
226
- const style = (0, react_1.useMemo)(() => {
227
- return {
228
- ...container,
229
- width: windowWidth,
230
- overflow: 'hidden',
231
- pointerEvents: 'none',
232
- };
233
- }, [windowWidth]);
234
- const ticks = (0, react_1.useMemo)(() => {
235
203
  const frameInterval = (0, timeline_scroll_logic_1.getFrameIncrementFromWidth)(durationInFrames, windowWidth);
236
204
  const maxTickLabelWidth = (0, render_frame_1.renderFrame)(durationInFrames - 1, fps).length *
237
205
  TICK_LABEL_FONT_SIZE *
238
206
  0.6;
239
- const minSpacingBetweenTickLabelsPx = TICK_LABEL_MARGIN_LEFT + maxTickLabelWidth + TICK_LABEL_MIN_GAP;
240
- const seconds = Math.floor(durationInFrames / fps);
241
- const rawSecondMarkerEveryNth = minSpacingBetweenTickLabelsPx / (frameInterval * fps);
242
207
  const tickScale = (0, exports.getTimelineTickScale)({
243
208
  fps,
244
209
  frameInterval,
245
- rawSecondMarkerEveryNth,
210
+ rawSecondMarkerEveryNth: (TICK_LABEL_MARGIN_LEFT + maxTickLabelWidth + TICK_LABEL_MIN_GAP) /
211
+ (frameInterval * fps),
246
212
  });
247
- // Labeled ticks use human-friendly time intervals.
248
- const secondTicks = [];
249
- for (let index = 0; index < seconds; index += tickScale.labelEverySeconds) {
250
- secondTicks.push({
251
- frame: index * fps,
252
- style: {
253
- ...secondTick,
254
- left: frameInterval * index * fps + timeline_layout_1.TIMELINE_PADDING,
255
- },
256
- showTime: index > 0,
257
- });
258
- }
259
- const hasSecondTick = new Set(secondTicks.map((t) => t.frame));
260
- const subdivisionTicks = [];
261
- const { minorTickEvery, mediumTickEvery } = tickScale;
262
- if ((minorTickEvery === null || minorTickEvery === void 0 ? void 0 : minorTickEvery.unit) === 'frames') {
263
- for (let frame = 0; frame < durationInFrames; frame += minorTickEvery.interval) {
264
- if (hasSecondTick.has(frame)) {
265
- continue;
266
- }
267
- subdivisionTicks.push({
268
- frame,
269
- style: {
270
- ...tick,
271
- left: frameInterval * frame + timeline_layout_1.TIMELINE_PADDING,
272
- height: (Number.isInteger(fps) && frame % fps === 0) ||
273
- ((mediumTickEvery === null || mediumTickEvery === void 0 ? void 0 : mediumTickEvery.unit) === 'frames' &&
274
- frame % mediumTickEvery.interval === 0)
275
- ? 5
276
- : 2,
277
- },
278
- showTime: false,
279
- });
213
+ const draw = () => {
214
+ const { clientWidth: width, scrollLeft } = scrollable;
215
+ const pixelRatio = window.devicePixelRatio;
216
+ const canvasWidth = Math.ceil(width * pixelRatio);
217
+ const canvasHeight = exports.TIMELINE_TIME_INDICATOR_HEIGHT * pixelRatio;
218
+ if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {
219
+ canvas.width = canvasWidth;
220
+ canvas.height = canvasHeight;
221
+ canvas.style.width = `${width}px`;
222
+ canvas.style.height = `${exports.TIMELINE_TIME_INDICATOR_HEIGHT}px`;
280
223
  }
281
- }
282
- if ((minorTickEvery === null || minorTickEvery === void 0 ? void 0 : minorTickEvery.unit) === 'seconds') {
283
- for (let second = 0; second < seconds; second += minorTickEvery.interval) {
224
+ context.resetTransform();
225
+ context.clearRect(0, 0, canvas.width, canvas.height);
226
+ context.scale(pixelRatio, pixelRatio);
227
+ context.fillStyle = colors_1.WHITE_ALPHA_15;
228
+ const firstFrame = Math.max(0, Math.floor((scrollLeft - timeline_layout_1.TIMELINE_PADDING) / frameInterval));
229
+ const lastFrame = Math.min(durationInFrames - 1, Math.ceil((scrollLeft + width - timeline_layout_1.TIMELINE_PADDING) / frameInterval));
230
+ const xForFrame = (frame) => Math.round(frameInterval * frame + timeline_layout_1.TIMELINE_PADDING - scrollLeft) + 0.5;
231
+ const drawTick = (frame, height) => {
232
+ const x = xForFrame(frame);
233
+ context.fillRect(x, 0, 1, height);
234
+ };
235
+ const firstLabelSecond = Math.ceil(firstFrame / fps / tickScale.labelEverySeconds) *
236
+ tickScale.labelEverySeconds;
237
+ const seconds = Math.floor(durationInFrames / fps);
238
+ for (let second = firstLabelSecond; second < seconds && second * fps <= lastFrame; second += tickScale.labelEverySeconds) {
284
239
  const frame = second * fps;
285
- if (hasSecondTick.has(frame)) {
286
- continue;
240
+ drawTick(frame, 15);
241
+ if (second > 0) {
242
+ context.fillStyle = colors_1.LIGHT_TEXT;
243
+ context.font = `${TICK_LABEL_FONT_SIZE}px ${getComputedStyle(canvas).fontFamily}`;
244
+ context.textBaseline = 'top';
245
+ context.fillText((0, render_frame_1.renderFrame)(frame, fps), xForFrame(frame) + TICK_LABEL_MARGIN_LEFT, 7);
246
+ context.fillStyle = colors_1.WHITE_ALPHA_15;
287
247
  }
288
- subdivisionTicks.push({
289
- frame,
290
- style: {
291
- ...tick,
292
- left: frameInterval * frame + timeline_layout_1.TIMELINE_PADDING,
293
- height: (mediumTickEvery === null || mediumTickEvery === void 0 ? void 0 : mediumTickEvery.unit) === 'seconds' &&
294
- second % mediumTickEvery.interval === 0
295
- ? 5
296
- : 2,
297
- },
298
- showTime: false,
299
- });
300
248
  }
301
- }
302
- return [...secondTicks, ...subdivisionTicks];
249
+ const { minorTickEvery, mediumTickEvery } = tickScale;
250
+ if ((minorTickEvery === null || minorTickEvery === void 0 ? void 0 : minorTickEvery.unit) === 'frames') {
251
+ const firstTick = Math.ceil(firstFrame / minorTickEvery.interval) *
252
+ minorTickEvery.interval;
253
+ for (let frame = firstTick; frame <= lastFrame; frame += minorTickEvery.interval) {
254
+ if (frame % (tickScale.labelEverySeconds * fps) === 0) {
255
+ continue;
256
+ }
257
+ drawTick(frame, (Number.isInteger(fps) && frame % fps === 0) ||
258
+ ((mediumTickEvery === null || mediumTickEvery === void 0 ? void 0 : mediumTickEvery.unit) === 'frames' &&
259
+ frame % mediumTickEvery.interval === 0)
260
+ ? 5
261
+ : 2);
262
+ }
263
+ }
264
+ if ((minorTickEvery === null || minorTickEvery === void 0 ? void 0 : minorTickEvery.unit) === 'seconds') {
265
+ const firstSecond = Math.ceil(firstFrame / fps / minorTickEvery.interval) *
266
+ minorTickEvery.interval;
267
+ for (let second = firstSecond; second < seconds && second * fps <= lastFrame; second += minorTickEvery.interval) {
268
+ if (second % tickScale.labelEverySeconds === 0) {
269
+ continue;
270
+ }
271
+ drawTick(second * fps, (mediumTickEvery === null || mediumTickEvery === void 0 ? void 0 : mediumTickEvery.unit) === 'seconds' &&
272
+ second % mediumTickEvery.interval === 0
273
+ ? 5
274
+ : 2);
275
+ }
276
+ }
277
+ };
278
+ const onScroll = () => {
279
+ draw();
280
+ };
281
+ const resizeObserver = new ResizeObserver(draw);
282
+ draw();
283
+ scrollable.addEventListener('scroll', onScroll);
284
+ resizeObserver.observe(scrollable);
285
+ return () => {
286
+ scrollable.removeEventListener('scroll', onScroll);
287
+ resizeObserver.disconnect();
288
+ };
303
289
  }, [durationInFrames, fps, windowWidth]);
304
- return (jsx_runtime_1.jsx("div", { ref: ref, style: style, children: ticks.map((t) => {
305
- return (jsx_runtime_1.jsx("div", { style: t.style, children: t.showTime ? (jsx_runtime_1.jsx("div", { style: tickLabel, children: (0, render_frame_1.renderFrame)(t.frame, fps) })) : null }, t.frame));
306
- }) }));
290
+ const style = (0, react_1.useMemo)(() => {
291
+ return {
292
+ ...container,
293
+ width: windowWidth,
294
+ overflow: 'hidden',
295
+ pointerEvents: 'none',
296
+ };
297
+ }, [windowWidth]);
298
+ return (jsx_runtime_1.jsx("div", { style: style, children: jsx_runtime_1.jsx("canvas", { ref: canvasRef, style: { position: 'absolute', top: 0, left: 0 } }) }));
307
299
  });
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
2
  export declare const TimelineTracks: React.NamedExoticComponent<{
4
- readonly timeline: TimelineTrackData[];
5
3
  readonly hasBeenCut: boolean;
6
4
  }>;
@@ -38,16 +38,18 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const timeline_layout_1 = require("../../helpers/timeline-layout");
40
40
  const MaxTimelineTracks_1 = require("./MaxTimelineTracks");
41
- const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
42
41
  const TimelineTrack_1 = require("./TimelineTrack");
42
+ const TimelineVirtualization_1 = require("./TimelineVirtualization");
43
43
  const content = {
44
44
  paddingLeft: timeline_layout_1.TIMELINE_PADDING,
45
45
  paddingRight: timeline_layout_1.TIMELINE_PADDING,
46
+ position: 'relative',
46
47
  };
47
48
  const timelineContent = {
48
49
  minHeight: '100%',
49
50
  };
50
- const TimelineTracksInner = ({ timeline, hasBeenCut }) => {
51
+ const TimelineTracksInner = ({ hasBeenCut }) => {
52
+ const { rows, tracksEnd, virtualItems } = (0, TimelineVirtualization_1.useTimelineVirtualization)();
51
53
  const timelineStyle = (0, react_1.useMemo)(() => {
52
54
  return {
53
55
  ...timelineContent,
@@ -55,7 +57,12 @@ const TimelineTracksInner = ({ timeline, hasBeenCut }) => {
55
57
  };
56
58
  }, []);
57
59
  return (jsx_runtime_1.jsxs("div", { style: timelineStyle, children: [
58
- jsx_runtime_1.jsxs("div", { style: content, children: [
59
- jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), timeline.map((track) => (jsx_runtime_1.jsx(TimelineTrack_1.TimelineTrack, { track: track }, track.sequence.id)))] }), hasBeenCut ? jsx_runtime_1.jsx(MaxTimelineTracks_1.MaxTimelineTracksReached, {}) : null] }));
60
+ jsx_runtime_1.jsx("div", { style: { ...content, height: tracksEnd }, children: virtualItems.map((virtualItem) => (jsx_runtime_1.jsx("div", { style: {
61
+ height: virtualItem.size,
62
+ left: timeline_layout_1.TIMELINE_PADDING,
63
+ position: 'absolute',
64
+ right: timeline_layout_1.TIMELINE_PADDING,
65
+ top: virtualItem.start,
66
+ }, children: jsx_runtime_1.jsx(TimelineTrack_1.TimelineTrack, { track: rows[virtualItem.index].track }) }, virtualItem.key))) }), hasBeenCut ? jsx_runtime_1.jsx(MaxTimelineTracks_1.MaxTimelineTracksReached, {}) : null] }));
60
67
  };
61
68
  exports.TimelineTracks = react_1.default.memo(TimelineTracksInner);
@@ -198,7 +198,7 @@ const TimelineTransformOriginField = ({ field, propStatus, effectiveValue, onSav
198
198
  serializeZ,
199
199
  ]);
200
200
  if (percent === null) {
201
- return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "unsupported origin" });
201
+ return (jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "unsupported origin", formattedValue: false }));
202
202
  }
203
203
  return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
204
204
  jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : percent[0], buttonStyle: leftDraggerStyle, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, "aria-label": "Transform origin X" }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : percent[1], buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, "aria-label": "Transform origin Y" }), show3D ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [