@remotion/studio 4.0.503 → 4.0.505

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 (181) hide show
  1. package/dist/api/install-package.d.ts +2 -1
  2. package/dist/api/install-package.js +6 -2
  3. package/dist/components/AssetSelectorItem.js +4 -16
  4. package/dist/components/AudioWaveform.d.ts +1 -1
  5. package/dist/components/AudioWaveform.js +36 -3
  6. package/dist/components/Canvas.js +12 -5
  7. package/dist/components/CheckboardToggle.js +3 -1
  8. package/dist/components/CompositionContextButton.d.ts +1 -1
  9. package/dist/components/CompositionContextButton.js +2 -2
  10. package/dist/components/CompositionSelector.js +2 -2
  11. package/dist/components/CompositionSelectorItem.js +6 -7
  12. package/dist/components/ContextMenu.d.ts +5 -7
  13. package/dist/components/ContextMenu.js +54 -21
  14. package/dist/components/ControlButton.d.ts +4 -2
  15. package/dist/components/ControlButton.js +6 -20
  16. package/dist/components/EditorContent.js +1 -1
  17. package/dist/components/EditorGuides/Guide.js +2 -2
  18. package/dist/components/EffectPickerModal.js +70 -9
  19. package/dist/components/FullscreenToggle.js +1 -2
  20. package/dist/components/InitialCompositionLoader.js +1 -14
  21. package/dist/components/InlineAction.d.ts +3 -4
  22. package/dist/components/InlineAction.js +16 -13
  23. package/dist/components/InlineDropdown.d.ts +3 -2
  24. package/dist/components/InlineDropdown.js +16 -5
  25. package/dist/components/InspectorPanel/CompositionMetadata.js +7 -6
  26. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +2 -2
  27. package/dist/components/InspectorPanel/KeyframeInspector.js +2 -3
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -1
  29. package/dist/components/InspectorPanel/common.js +24 -34
  30. package/dist/components/InspectorPanel/styles.js +4 -0
  31. package/dist/components/InspectorSequenceSection.js +1 -1
  32. package/dist/components/LoopToggle.js +1 -1
  33. package/dist/components/Menu/MenuItem.js +16 -12
  34. package/dist/components/MenuBuildIndicator.d.ts +3 -1
  35. package/dist/components/MenuBuildIndicator.js +14 -59
  36. package/dist/components/MenuCompositionName.js +3 -63
  37. package/dist/components/MenuToolbar.js +23 -3
  38. package/dist/components/MobilePanel.d.ts +1 -2
  39. package/dist/components/MobilePanel.js +6 -10
  40. package/dist/components/MuteToggle.js +2 -1
  41. package/dist/components/NewComposition/ComboBox.d.ts +1 -0
  42. package/dist/components/NewComposition/ComboBox.js +2 -2
  43. package/dist/components/NewComposition/InputDragger.d.ts +5 -0
  44. package/dist/components/NewComposition/InputDragger.js +11 -6
  45. package/dist/components/NewComposition/MenuContent.d.ts +1 -1
  46. package/dist/components/NewComposition/menu-typeahead.d.ts +1 -1
  47. package/dist/components/Notifications/NotificationCenter.js +12 -2
  48. package/dist/components/OutlineToggle.js +10 -2
  49. package/dist/components/PlayPause.js +2 -6
  50. package/dist/components/PlaybackRateSelector.js +4 -9
  51. package/dist/components/PreviewToolbar.js +12 -8
  52. package/dist/components/PreviewToolbarOverflowButton.d.ts +0 -1
  53. package/dist/components/PreviewToolbarOverflowButton.js +2 -75
  54. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -2
  55. package/dist/components/RenderButton.d.ts +1 -1
  56. package/dist/components/RenderButton.js +55 -37
  57. package/dist/components/RenderModal/FrameRangeSetting.js +6 -1
  58. package/dist/components/RenderModal/MultiRangeSlider.js +8 -8
  59. package/dist/components/RenderModal/RenderModalEnvironmentVariables.js +1 -9
  60. package/dist/components/RenderModal/RenderModalOutputName.js +11 -2
  61. package/dist/components/RenderModal/ServerRenderModal.js +2 -17
  62. package/dist/components/RenderModal/WebRenderModal.js +3 -17
  63. package/dist/components/RenderModal/layout.js +7 -5
  64. package/dist/components/RenderModal/render-modals.js +18 -15
  65. package/dist/components/RenderQueue/RenderQueueRepeat.js +1 -14
  66. package/dist/components/SelectedOutlineElement.js +13 -22
  67. package/dist/components/SelectedOutlineOverlay.js +5 -1
  68. package/dist/components/SidebarRenderButton.js +1 -15
  69. package/dist/components/SizeSelector.js +4 -9
  70. package/dist/components/SnappingToggle.js +1 -2
  71. package/dist/components/Spinner.d.ts +1 -0
  72. package/dist/components/Spinner.js +2 -2
  73. package/dist/components/Splitter/SplitterContainer.d.ts +1 -0
  74. package/dist/components/Splitter/SplitterContainer.js +4 -1
  75. package/dist/components/Splitter/SplitterContext.d.ts +4 -3
  76. package/dist/components/Splitter/SplitterContext.js +3 -2
  77. package/dist/components/Splitter/SplitterElement.js +6 -1
  78. package/dist/components/Splitter/SplitterHandle.js +1 -0
  79. package/dist/components/Tabs/vertical.d.ts +1 -0
  80. package/dist/components/Tabs/vertical.js +8 -10
  81. package/dist/components/TimeValue.js +26 -8
  82. package/dist/components/Timeline/Timeline.js +5 -5
  83. package/dist/components/Timeline/TimelineClipboardKeybindings.js +3 -6
  84. package/dist/components/Timeline/TimelineDeleteKeybindings.js +5 -7
  85. package/dist/components/Timeline/TimelineDragHandler.js +3 -0
  86. package/dist/components/Timeline/TimelineEffectItem.js +6 -2
  87. package/dist/components/Timeline/TimelineEffectPropItem.js +6 -3
  88. package/dist/components/Timeline/TimelineExpandedKeyframeRow.d.ts +6 -6
  89. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +34 -2
  90. package/dist/components/Timeline/TimelineHeightContainer.d.ts +1 -0
  91. package/dist/components/Timeline/TimelineHeightContainer.js +2 -2
  92. package/dist/components/Timeline/TimelineInOutDragHandler.js +3 -3
  93. package/dist/components/Timeline/TimelineKeyframeEasingLine.d.ts +5 -3
  94. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +32 -30
  95. package/dist/components/Timeline/TimelineList.d.ts +1 -0
  96. package/dist/components/Timeline/TimelineList.js +2 -3
  97. package/dist/components/Timeline/TimelineScaleField.js +1 -1
  98. package/dist/components/Timeline/TimelineSelection.js +2 -3
  99. package/dist/components/Timeline/TimelineSequence.js +34 -28
  100. package/dist/components/Timeline/TimelineSequenceItem.d.ts +3 -3
  101. package/dist/components/Timeline/TimelineSequenceItem.js +34 -23
  102. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +10 -2
  103. package/dist/components/Timeline/TimelineSequencePropItem.js +64 -12
  104. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +2 -2
  105. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +38 -5
  106. package/dist/components/Timeline/TimelineTimeIndicators.js +36 -3
  107. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -1
  108. package/dist/components/Timeline/TimelineVideoInfo.js +36 -3
  109. package/dist/components/Timeline/TimelineZoomControls.d.ts +3 -1
  110. package/dist/components/Timeline/TimelineZoomControls.js +59 -20
  111. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +2 -3
  112. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +1 -1
  113. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +7 -18
  114. package/dist/components/Timeline/use-timeline-asset-drop.js +3 -3
  115. package/dist/components/Timeline/use-timeline-height.d.ts +2 -1
  116. package/dist/components/Timeline/use-timeline-height.js +3 -2
  117. package/dist/components/TimelineCombobox.d.ts +11 -0
  118. package/dist/components/TimelineCombobox.js +181 -0
  119. package/dist/components/TimelineInOutToggle.js +3 -3
  120. package/dist/components/TopPanel.js +8 -8
  121. package/dist/components/UndoRedoButtons.js +6 -5
  122. package/dist/components/UpdateCheck.js +18 -5
  123. package/dist/components/UpdateModal/UpdateModal.js +35 -12
  124. package/dist/components/composition-menu-items.d.ts +2 -4
  125. package/dist/components/composition-menu-items.js +31 -54
  126. package/dist/components/import-assets.d.ts +2 -1
  127. package/dist/components/import-assets.js +1 -1
  128. package/dist/components/selected-outline-types.d.ts +1 -1
  129. package/dist/esm/{chunk-bj1r1hh5.js → chunk-7pgk8h5m.js} +9174 -8486
  130. package/dist/esm/internals.mjs +9174 -8486
  131. package/dist/esm/previewEntry.mjs +8991 -8303
  132. package/dist/esm/renderEntry.mjs +1 -1
  133. package/dist/helpers/hoverable.d.ts +11 -0
  134. package/dist/helpers/hoverable.js +70 -0
  135. package/dist/helpers/inject-css.js +43 -23
  136. package/dist/helpers/install-required-package.d.ts +3 -2
  137. package/dist/helpers/install-required-package.js +20 -15
  138. package/dist/helpers/use-is-fullscreen.d.ts +1 -0
  139. package/dist/helpers/use-is-fullscreen.js +25 -0
  140. package/dist/helpers/use-menu-structure.js +88 -59
  141. package/dist/icons/audio.d.ts +1 -1
  142. package/dist/icons/audio.js +1 -1
  143. package/dist/icons/canvas-zoom.d.ts +10 -0
  144. package/dist/icons/canvas-zoom.js +21 -0
  145. package/dist/icons/caret.js +1 -1
  146. package/dist/icons/certificate.d.ts +1 -1
  147. package/dist/icons/certificate.js +1 -1
  148. package/dist/icons/data.d.ts +1 -1
  149. package/dist/icons/data.js +2 -2
  150. package/dist/icons/effects.d.ts +5 -0
  151. package/dist/icons/effects.js +8 -0
  152. package/dist/icons/ellipsis.js +1 -1
  153. package/dist/icons/external-link.d.ts +5 -0
  154. package/dist/icons/external-link.js +10 -0
  155. package/dist/icons/fullscreen.js +1 -1
  156. package/dist/icons/gear.d.ts +1 -1
  157. package/dist/icons/gear.js +1 -1
  158. package/dist/icons/gif.d.ts +1 -1
  159. package/dist/icons/gif.js +1 -1
  160. package/dist/icons/input-props.d.ts +2 -0
  161. package/dist/icons/input-props.js +9 -0
  162. package/dist/icons/jump-to-start.js +2 -2
  163. package/dist/icons/magnet.d.ts +3 -1
  164. package/dist/icons/magnet.js +2 -2
  165. package/dist/icons/media-volume.d.ts +6 -2
  166. package/dist/icons/media-volume.js +8 -6
  167. package/dist/icons/minus.d.ts +3 -1
  168. package/dist/icons/minus.js +2 -2
  169. package/dist/icons/pause.js +1 -1
  170. package/dist/icons/play.js +1 -1
  171. package/dist/icons/playback-rate.d.ts +5 -0
  172. package/dist/icons/playback-rate.js +31 -0
  173. package/dist/icons/plus.js +1 -1
  174. package/dist/icons/redo.js +2 -2
  175. package/dist/icons/search.d.ts +5 -0
  176. package/dist/icons/search.js +10 -0
  177. package/dist/icons/step-back.js +2 -2
  178. package/dist/icons/step-forward.js +2 -2
  179. package/dist/icons/timelineInOutPointer.js +2 -2
  180. package/dist/icons/undo.js +2 -2
  181. package/package.json +12 -12
@@ -12,13 +12,14 @@ const selectorButton = {
12
12
  paddingLeft: 16,
13
13
  display: 'flex',
14
14
  flexDirection: 'row',
15
+ fontFamily: 'sans-serif',
15
16
  fontSize: 14,
16
17
  color: 'inherit',
17
18
  alignItems: 'center',
18
19
  userSelect: 'none',
19
20
  WebkitUserSelect: 'none',
20
21
  };
21
- const VerticalTab = ({ children, onClick, style, selected }) => {
22
+ const VerticalTab = ({ children, onClick, renderIcon, style, selected }) => {
22
23
  const [hovered, setHovered] = (0, react_1.useState)(false);
23
24
  const { tabIndex } = (0, z_index_1.useZIndex)();
24
25
  const onPointerEnter = (0, react_1.useCallback)(() => {
@@ -27,19 +28,16 @@ const VerticalTab = ({ children, onClick, style, selected }) => {
27
28
  const onPointerLeave = (0, react_1.useCallback)(() => {
28
29
  setHovered(false);
29
30
  }, []);
31
+ const color = selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT;
30
32
  const definiteStyle = (0, react_1.useMemo)(() => {
31
33
  return {
32
34
  ...selectorButton,
33
- backgroundColor: selected
34
- ? colors_1.SELECTED_BACKGROUND
35
- : hovered
36
- ? colors_1.WHITE_ALPHA_06
37
- : colors_1.TRANSPARENT,
38
- color: selected ? colors_1.WHITE : colors_1.LIGHT_TEXT,
39
- boxShadow: selected ? 'none' : undefined,
35
+ backgroundColor: selected || hovered ? colors_1.WHITE_ALPHA_06 : colors_1.TRANSPARENT,
36
+ color,
37
+ boxShadow: 'none',
40
38
  ...style,
41
39
  };
42
- }, [hovered, selected, style]);
43
- return (jsx_runtime_1.jsx("button", { style: definiteStyle, type: "button", onClick: onClick, tabIndex: tabIndex, onPointerLeave: onPointerLeave, onPointerEnter: onPointerEnter, children: children }));
40
+ }, [color, hovered, selected, style]);
41
+ return (jsx_runtime_1.jsxs("button", { style: definiteStyle, type: "button", onClick: onClick, tabIndex: tabIndex, onPointerLeave: onPointerLeave, onPointerEnter: onPointerEnter, children: [renderIcon ? renderIcon(color) : null, children] }));
44
42
  };
45
43
  exports.VerticalTab = VerticalTab;
@@ -11,6 +11,7 @@ const use_keybinding_1 = require("../helpers/use-keybinding");
11
11
  const render_frame_1 = require("../state/render-frame");
12
12
  const layout_1 = require("./layout");
13
13
  const InputDragger_1 = require("./NewComposition/InputDragger");
14
+ const TimelineZoomControls_1 = require("./Timeline/TimelineZoomControls");
14
15
  const text = {
15
16
  color: colors_1.WHITE,
16
17
  display: 'flex',
@@ -20,19 +21,32 @@ const text = {
20
21
  lineHeight: 1,
21
22
  width: '100%',
22
23
  };
23
- const time = {
24
+ const currentTimeTypography = {
25
+ color: colors_1.WHITE,
24
26
  display: 'inline-block',
25
- fontSize: 16,
27
+ fontSize: 14,
28
+ fontVariantNumeric: 'tabular-nums',
29
+ fontWeight: 400,
26
30
  lineHeight: 1,
27
31
  fontFamily: 'monospace',
28
32
  };
29
- const frameStyle = {
33
+ const currentTimeInputStyle = {
34
+ ...currentTimeTypography,
35
+ padding: '4px 6px 4px 0',
36
+ };
37
+ const currentTimeButtonStyle = {
38
+ paddingLeft: 0,
39
+ transform: 'translateY(-1px)',
40
+ };
41
+ const currentTimeSubtitle = {
30
42
  color: colors_1.LIGHT_TEXT,
31
- fontWeight: 500,
32
- lineHeight: 1,
33
- fontSize: 16,
43
+ display: 'block',
34
44
  fontFamily: 'monospace',
35
- paddingRight: 10,
45
+ fontSize: 10,
46
+ fontWeight: 400,
47
+ lineHeight: 1,
48
+ marginTop: -2,
49
+ textAlign: 'left',
36
50
  };
37
51
  const TimeValue = () => {
38
52
  const frame = (0, remotion_1.useCurrentFrame)();
@@ -47,6 +61,10 @@ const TimeValue = () => {
47
61
  const onValueChange = (0, react_1.useCallback)((val) => {
48
62
  seek(val);
49
63
  }, [seek]);
64
+ const formatter = (0, react_1.useCallback)((value) => {
65
+ return config ? (0, render_frame_1.renderFrame)(Number(value), config.fps) : String(value);
66
+ }, [config]);
67
+ const formatterSubtitle = (0, react_1.useCallback)((value) => String(value), []);
50
68
  (0, react_1.useImperativeHandle)(remotion_1.Internals.timeValueRef, () => ({
51
69
  goToFrame: () => {
52
70
  var _a;
@@ -81,7 +99,7 @@ const TimeValue = () => {
81
99
  return null;
82
100
  }
83
101
  return (jsx_runtime_1.jsxs("div", { style: text, children: [
84
- jsx_runtime_1.jsx("div", { style: time, children: (0, render_frame_1.renderFrame)(frame, config.fps) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { ref: ref, value: frame, onTextChange: onTextChange, onValueChange: onValueChange, rightAlign: true, status: "ok", style: frameStyle })
102
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { ref: ref, "aria-label": String(frame), value: frame, onTextChange: onTextChange, onValueChange: onValueChange, formatter: formatter, formatterStyle: currentTimeTypography, formatterSubtitle: formatterSubtitle, formatterSubtitleStyle: currentTimeSubtitle, buttonStyle: currentTimeButtonStyle, rightAlign: false, status: "ok", style: currentTimeInputStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(TimelineZoomControls_1.TimelineZoomControls, { sliderMaxWidth: 80 }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
85
103
  ] }));
86
104
  };
87
105
  exports.TimeValue = TimeValue;
@@ -195,7 +195,7 @@ const TimelineContextMenuArea = ({ children }) => {
195
195
  setIsAddingAsset(false);
196
196
  }
197
197
  }, [canInsertAsset, compositionFile, currentCompositionId, videoConfig]);
198
- const contextMenuItems = (0, react_1.useMemo)(() => {
198
+ const getContextMenuItems = (0, react_1.useCallback)(() => {
199
199
  return [
200
200
  {
201
201
  type: 'item',
@@ -223,7 +223,7 @@ const TimelineContextMenuArea = ({ children }) => {
223
223
  },
224
224
  ];
225
225
  }, [insertSolid, canInsertSolid, insertAsset, canInsertAsset]);
226
- return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { ref: timeline_refs_1.timelineVerticalScroll, values: contextMenuItems, onOpen: null, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(timeline_asset_drop_context_1.TimelineAssetDropFrameContext.Provider, { value: assetDropFrame, children: children }) }));
226
+ return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { ref: timeline_refs_1.timelineVerticalScroll, getItems: getContextMenuItems, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(timeline_asset_drop_context_1.TimelineAssetDropFrameContext.Provider, { value: assetDropFrame, children: children }) }));
227
227
  };
228
228
  const TimelineInner = () => {
229
229
  var _a;
@@ -267,9 +267,9 @@ const TimelineInner = () => {
267
267
  return null;
268
268
  }
269
269
  return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
270
- }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
271
- jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, children: [
272
- jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
270
+ }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, isStill: isStill, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown, showTimePadding: false })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
271
+ jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
272
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown, showTimePadding: true }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
273
273
  jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null, jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
274
274
  ] }) })
275
275
  ] })
@@ -18,6 +18,7 @@ const call_update_keyframe_settings_1 = require("./call-update-keyframe-settings
18
18
  const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
19
19
  const effects_clipboard_1 = require("./effects-clipboard");
20
20
  const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
21
+ const imperative_state_1 = require("./imperative-state");
21
22
  const keyframe_clipboard_1 = require("./keyframe-clipboard");
22
23
  const save_effect_prop_1 = require("./save-effect-prop");
23
24
  const TimelineSelection_1 = require("./TimelineSelection");
@@ -379,9 +380,6 @@ const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequen
379
380
  exports.getPasteEffectPropTarget = getPasteEffectPropTarget;
380
381
  const TimelineClipboardKeybindings = () => {
381
382
  const keybindings = (0, use_keybinding_1.useKeybinding)();
382
- const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
383
- const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
384
- timelinePositionRef.current = timelinePosition;
385
383
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
386
384
  const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
387
385
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
@@ -556,7 +554,7 @@ const TimelineClipboardKeybindings = () => {
556
554
  clientId,
557
555
  confirm,
558
556
  propStatuses,
559
- timelinePosition: timelinePositionRef.current,
557
+ timelinePosition: (0, imperative_state_1.getCurrentFrame)(),
560
558
  });
561
559
  return deletePromise === null || deletePromise === void 0 ? void 0 : deletePromise.then((deleted) => {
562
560
  if (!deleted) {
@@ -612,7 +610,7 @@ const TimelineClipboardKeybindings = () => {
612
610
  const keyframeTarget = (0, keyframe_clipboard_1.getPasteKeyframeTarget)({
613
611
  selectedItems,
614
612
  payload: keyframeResult.data,
615
- timelinePosition: timelinePositionRef.current,
613
+ timelinePosition: (0, imperative_state_1.getCurrentFrame)(),
616
614
  sequences,
617
615
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
618
616
  propStatuses,
@@ -870,7 +868,6 @@ const TimelineClipboardKeybindings = () => {
870
868
  previewServerState,
871
869
  sequencesRef,
872
870
  setPropStatuses,
873
- timelinePositionRef,
874
871
  ]);
875
872
  return null;
876
873
  };
@@ -10,6 +10,7 @@ const editor_guides_1 = require("../../state/editor-guides");
10
10
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
11
11
  const delete_selected_timeline_item_1 = require("./delete-selected-timeline-item");
12
12
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
13
+ const imperative_state_1 = require("./imperative-state");
13
14
  const reset_selected_timeline_props_1 = require("./reset-selected-timeline-props");
14
15
  const split_selected_timeline_item_1 = require("./split-selected-timeline-item");
15
16
  const TimelineSelection_1 = require("./TimelineSelection");
@@ -25,15 +26,13 @@ const TimelineDeleteKeybindings = () => {
25
26
  const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
26
27
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
27
28
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
28
- const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
29
- const timelinePositionRef = (0, react_1.useRef)(timelinePosition);
30
- timelinePositionRef.current = timelinePosition;
31
29
  (0, react_1.useEffect)(() => {
32
30
  if (!canSelect || previewServerState.type !== 'connected') {
33
31
  return;
34
32
  }
35
33
  const { clientId } = previewServerState;
36
34
  const handleDelete = () => {
35
+ const timelinePosition = (0, imperative_state_1.getCurrentFrame)();
37
36
  const { selectedItems, clearSelection, selectItems } = currentSelection.current;
38
37
  const sequences = sequencesRef.current;
39
38
  const propStatuses = propStatusesRef.current;
@@ -58,7 +57,7 @@ const TimelineDeleteKeybindings = () => {
58
57
  clientId,
59
58
  confirm,
60
59
  propStatuses,
61
- timelinePosition: timelinePositionRef.current,
60
+ timelinePosition,
62
61
  });
63
62
  if (deletePromise !== null) {
64
63
  deletePromise
@@ -69,7 +68,7 @@ const TimelineDeleteKeybindings = () => {
69
68
  sequences,
70
69
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
71
70
  propStatuses,
72
- timelinePosition: timelinePositionRef.current,
71
+ timelinePosition,
73
72
  });
74
73
  if (nextSelection.length === 0) {
75
74
  clearSelection();
@@ -169,7 +168,7 @@ const TimelineDeleteKeybindings = () => {
169
168
  sequences: sequencesRef.current,
170
169
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
171
170
  propStatuses: propStatusesRef.current,
172
- splitFrame: timelinePositionRef.current,
171
+ splitFrame: (0, imperative_state_1.getCurrentFrame)(),
173
172
  });
174
173
  if (splitPromise === null) {
175
174
  return;
@@ -198,7 +197,6 @@ const TimelineDeleteKeybindings = () => {
198
197
  sequencesRef,
199
198
  setGuidesList,
200
199
  setPropStatuses,
201
- timelinePositionRef,
202
200
  ]);
203
201
  return null;
204
202
  };
@@ -247,6 +247,9 @@ const TimelineDragHandlerInner = () => {
247
247
  extrapolate: 'clamp',
248
248
  });
249
249
  setFrame((c) => {
250
+ if (c[videoConfig.id] === frame) {
251
+ return c;
252
+ }
250
253
  const newObj = { ...c, [videoConfig.id]: frame };
251
254
  remotion_1.Internals.persistCurrentFrame(newObj);
252
255
  return newObj;
@@ -120,10 +120,13 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
120
120
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
121
121
  }
122
122
  }, [deleteDisabled, effectIndex, nodePath, validatedLocation.source]);
123
- const contextMenuValues = (0, react_1.useMemo)(() => {
123
+ const getContextMenuItems = (0, react_1.useCallback)(() => {
124
124
  if (!previewConnected) {
125
125
  return [];
126
126
  }
127
+ if (selection.selectable) {
128
+ selection.onSelect({ shiftKey: false, toggleKey: false });
129
+ }
127
130
  const items = [];
128
131
  if (documentationLink) {
129
132
  items.push({
@@ -168,6 +171,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
168
171
  documentationLink,
169
172
  onDeleteEffectFromSource,
170
173
  previewConnected,
174
+ selection,
171
175
  ]);
172
176
  const onToggle = (0, react_1.useCallback)((type) => {
173
177
  if (!canToggle || previewServerState.type !== 'connected') {
@@ -322,6 +326,6 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
322
326
  }, [dropIndicator]);
323
327
  const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: null, children: jsx_runtime_1.jsx("span", { title: label, style: labelStyle, children: label }) }));
324
328
  const draggableRow = canReorder ? (jsx_runtime_1.jsxs("div", { draggable: true, onDragStart: onDragStart, onDragEnd: onDragEnd, onDragOver: onDragOver, onDragLeave: onDragLeave, onDrop: onDrop, style: reorderWrapper, children: [reorderLineStyle ? jsx_runtime_1.jsx("div", { style: reorderLineStyle }) : null, row] })) : (row);
325
- return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: draggableRow })) : (draggableRow);
329
+ return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: draggableRow })) : (draggableRow);
326
330
  };
327
331
  exports.TimelineEffectItem = TimelineEffectItem;
@@ -294,7 +294,10 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
294
294
  setPropStatuses,
295
295
  validatedLocation.source,
296
296
  ]);
297
- const contextMenuValues = (0, react_1.useMemo)(() => {
297
+ const getContextMenuItems = (0, react_1.useCallback)(() => {
298
+ if (selection.selectable) {
299
+ selection.onSelect({ shiftKey: false, toggleKey: false });
300
+ }
298
301
  return [
299
302
  {
300
303
  type: 'item',
@@ -309,7 +312,7 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
309
312
  value: 'reset-effect-field',
310
313
  },
311
314
  ];
312
- }, [canShowReset, onReset]);
315
+ }, [canShowReset, onReset, selection]);
313
316
  const onPropertyDoubleClick = (0, react_1.useCallback)((event) => {
314
317
  if (!window.remotion_editorName ||
315
318
  previewServerState.type !== 'connected') {
@@ -322,6 +325,6 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
322
325
  }).catch(() => undefined);
323
326
  }, [field.key, previewServerState.type, validatedLocation]);
324
327
  const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, children: jsx_runtime_1.jsx(exports.TimelineEffectPropValue, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, sourceFrame: sourceFrame }) }) }));
325
- return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: row }));
328
+ return jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: row });
326
329
  };
327
330
  exports.TimelineEffectPropItem = TimelineEffectPropItem;
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
- export declare const TimelineExpandedKeyframeRow: React.NamedExoticComponent<{
3
+ import type { getTimelineKeyframes } from './get-timeline-keyframes';
4
+ type TimelineExpandedKeyframeRowProps = {
4
5
  readonly height: number;
5
- readonly keyframes: {
6
- frame: number;
7
- value: unknown;
8
- }[];
6
+ readonly keyframes: ReturnType<typeof getTimelineKeyframes>;
9
7
  readonly canEditEasing: boolean;
10
8
  readonly nodePathInfo: SequenceNodePathInfo;
11
9
  readonly showSeparator: boolean;
12
- }>;
10
+ };
11
+ export declare const TimelineExpandedKeyframeRow: React.NamedExoticComponent<TimelineExpandedKeyframeRowProps>;
12
+ export {};
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.TimelineExpandedKeyframeRow = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const studio_shared_1 = require("@remotion/studio-shared");
38
39
  const react_1 = __importStar(require("react"));
39
40
  const timeline_layout_1 = require("../../helpers/timeline-layout");
40
41
  const get_timeline_easing_segments_1 = require("./get-timeline-easing-segments");
@@ -43,6 +44,7 @@ const TimelineKeyframeEasingLine_1 = require("./TimelineKeyframeEasingLine");
43
44
  const TimelineSelection_1 = require("./TimelineSelection");
44
45
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
45
46
  const rowClipper = {
47
+ boxSizing: 'border-box',
46
48
  marginLeft: -timeline_layout_1.TIMELINE_PADDING,
47
49
  marginRight: -timeline_layout_1.TIMELINE_PADDING,
48
50
  overflow: 'hidden',
@@ -61,7 +63,37 @@ const TimelineExpandedKeyframeRowUnmemoized = ({ height, keyframes, canEditEasin
61
63
  const easingSegments = canEditEasing
62
64
  ? (0, get_timeline_easing_segments_1.getTimelineEasingSegments)(keyframes)
63
65
  : [];
64
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showSeparator ? jsx_runtime_1.jsx("div", { style: rowSeparator }) : null, jsx_runtime_1.jsx("div", { style: { ...rowClipper, height }, children: jsx_runtime_1.jsxs("div", { style: { ...row, height }, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, easingSegments.map((segment) => (jsx_runtime_1.jsx(TimelineKeyframeEasingLine_1.TimelineKeyframeEasingLine, { fromFrame: segment.fromFrame, toFrame: segment.toFrame, rowHeight: height, nodePathInfo: nodePathInfo, segmentIndex: segment.segmentIndex }, `${segment.segmentIndex}-${segment.fromFrame}-${segment.toFrame}`))), keyframes.map((keyframe) => (jsx_runtime_1.jsx(TimelineKeyframeDiamond_1.TimelineKeyframeDiamond, { frame: keyframe.frame, rowHeight: height, nodePathInfo: nodePathInfo }, keyframe.frame)))] }) })
66
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showSeparator ? jsx_runtime_1.jsx("div", { style: rowSeparator }) : null, jsx_runtime_1.jsx("div", { style: { ...rowClipper, height, width: timelineWidth !== null && timelineWidth !== void 0 ? timelineWidth : undefined }, children: jsx_runtime_1.jsxs("div", { style: { ...row, height }, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, easingSegments.map((segment) => (jsx_runtime_1.jsx(TimelineKeyframeEasingLine_1.TimelineKeyframeEasingLine, { fromFrame: segment.fromFrame, toFrame: segment.toFrame, rowHeight: height, nodePathInfo: nodePathInfo, segmentIndex: segment.segmentIndex }, `${segment.segmentIndex}-${segment.fromFrame}-${segment.toFrame}`))), keyframes.map((keyframe) => (jsx_runtime_1.jsx(TimelineKeyframeDiamond_1.TimelineKeyframeDiamond, { frame: keyframe.frame, rowHeight: height, nodePathInfo: nodePathInfo }, keyframe.frame)))] }) })
65
67
  ] }));
66
68
  };
67
- exports.TimelineExpandedKeyframeRow = react_1.default.memo(TimelineExpandedKeyframeRowUnmemoized);
69
+ const areTimelineExpandedKeyframeRowPropsEqual = (prevProps, nextProps) => {
70
+ if (prevProps.height !== nextProps.height ||
71
+ prevProps.canEditEasing !== nextProps.canEditEasing ||
72
+ prevProps.showSeparator !== nextProps.showSeparator ||
73
+ prevProps.keyframes.length !== nextProps.keyframes.length ||
74
+ prevProps.nodePathInfo.index !== nextProps.nodePathInfo.index ||
75
+ prevProps.nodePathInfo.numberOfSequencesWithThisNodePath !==
76
+ nextProps.nodePathInfo.numberOfSequencesWithThisNodePath ||
77
+ prevProps.nodePathInfo.supportsEffects !==
78
+ nextProps.nodePathInfo.supportsEffects ||
79
+ (0, studio_shared_1.stringifySequenceSubscriptionKey)(prevProps.nodePathInfo.sequenceSubscriptionKey) !==
80
+ (0, studio_shared_1.stringifySequenceSubscriptionKey)(nextProps.nodePathInfo.sequenceSubscriptionKey) ||
81
+ prevProps.nodePathInfo.auxiliaryKeys.length !==
82
+ nextProps.nodePathInfo.auxiliaryKeys.length) {
83
+ return false;
84
+ }
85
+ const prevVideoConfig = prevProps.nodePathInfo.sequenceSubscriptionKey.videoConfigValues;
86
+ const nextVideoConfig = nextProps.nodePathInfo.sequenceSubscriptionKey.videoConfigValues;
87
+ if (prevVideoConfig !== nextVideoConfig &&
88
+ (prevVideoConfig === null ||
89
+ nextVideoConfig === null ||
90
+ prevVideoConfig.durationInFrames !== nextVideoConfig.durationInFrames ||
91
+ prevVideoConfig.fps !== nextVideoConfig.fps ||
92
+ prevVideoConfig.height !== nextVideoConfig.height ||
93
+ prevVideoConfig.width !== nextVideoConfig.width)) {
94
+ return false;
95
+ }
96
+ return (prevProps.keyframes.every((keyframe, index) => keyframe.frame === nextProps.keyframes[index].frame) &&
97
+ prevProps.nodePathInfo.auxiliaryKeys.every((key, index) => key === nextProps.nodePathInfo.auxiliaryKeys[index]));
98
+ };
99
+ exports.TimelineExpandedKeyframeRow = react_1.default.memo(TimelineExpandedKeyframeRowUnmemoized, areTimelineExpandedKeyframeRowPropsEqual);
@@ -3,5 +3,6 @@ import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort
3
3
  export declare const TimelineHeightContainer: React.NamedExoticComponent<{
4
4
  readonly shown: TimelineTrackData[];
5
5
  readonly hasBeenCut: boolean;
6
+ readonly isStill: boolean;
6
7
  readonly children: React.ReactNode;
7
8
  }>;
@@ -45,8 +45,8 @@ const baseStyle = {
45
45
  overflowX: 'hidden',
46
46
  backgroundColor: TimelineSelection_1.TIMELINE_BACKGROUND,
47
47
  };
48
- const TimelineHeightContainerInner = ({ shown, hasBeenCut, children }) => {
49
- const height = (0, use_timeline_height_1.useTimelineHeight)({ shown, hasBeenCut });
48
+ const TimelineHeightContainerInner = ({ shown, hasBeenCut, isStill, children }) => {
49
+ const height = (0, use_timeline_height_1.useTimelineHeight)({ shown, hasBeenCut, isStill });
50
50
  const style = (0, react_1.useMemo)(() => ({ ...baseStyle, height }), [height]);
51
51
  return jsx_runtime_1.jsx("div", { style: style, children: children });
52
52
  };
@@ -302,7 +302,7 @@ const TimelineInOutDragHandlerInner = () => {
302
302
  (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
303
303
  };
304
304
  }, []);
305
- const inContextMenu = (0, react_1.useMemo)(() => {
305
+ const getInContextMenuItems = (0, react_1.useCallback)(() => {
306
306
  return [
307
307
  {
308
308
  id: 'hide-in',
@@ -330,7 +330,7 @@ const TimelineInOutDragHandlerInner = () => {
330
330
  },
331
331
  ];
332
332
  }, [setInAndOutFrames, videoConfig.id]);
333
- const outContextMenu = (0, react_1.useMemo)(() => {
333
+ const getOutContextMenuItems = (0, react_1.useCallback)(() => {
334
334
  return [
335
335
  {
336
336
  id: 'hide-out',
@@ -358,6 +358,6 @@ const TimelineInOutDragHandlerInner = () => {
358
358
  },
359
359
  ];
360
360
  }, [setInAndOutFrames, videoConfig.id]);
361
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [inFrame !== null && (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: inContextMenu, onOpen: null, children: jsx_runtime_1.jsx(TimelineInOutPointerHandle_1.TimelineInOutPointerHandle, { type: "in", atFrame: inFrame, dragging: inOutDragging.dragging === 'in', onPointerDown: onInPointerDown }) })), outFrame !== null && (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: outContextMenu, onOpen: null, children: jsx_runtime_1.jsx(TimelineInOutPointerHandle_1.TimelineInOutPointerHandle, { type: "out", dragging: inOutDragging.dragging === 'out', atFrame: outFrame, onPointerDown: onOutPointerDown }) }))] }));
361
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [inFrame !== null && (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getInContextMenuItems, children: jsx_runtime_1.jsx(TimelineInOutPointerHandle_1.TimelineInOutPointerHandle, { type: "in", atFrame: inFrame, dragging: inOutDragging.dragging === 'in', onPointerDown: onInPointerDown }) })), outFrame !== null && (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getOutContextMenuItems, children: jsx_runtime_1.jsx(TimelineInOutPointerHandle_1.TimelineInOutPointerHandle, { type: "out", dragging: inOutDragging.dragging === 'out', atFrame: outFrame, onPointerDown: onOutPointerDown }) }))] }));
362
362
  };
363
363
  const TimelineInOutDragHandlerInnerMemo = react_1.default.memo(TimelineInOutDragHandlerInner);
@@ -1,13 +1,15 @@
1
1
  import React from 'react';
2
2
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
3
  export declare const getTimelineKeyframeEasingLineStyle: (selected: boolean) => React.CSSProperties;
4
- export declare const TimelineKeyframeEasingLineVisual: React.FC<{
4
+ export declare const TimelineKeyframeEasingLineVisual: React.NamedExoticComponent<{
5
5
  readonly selected: boolean;
6
6
  }>;
7
- export declare const TimelineKeyframeEasingLine: React.NamedExoticComponent<{
7
+ type TimelineKeyframeEasingLineProps = {
8
8
  readonly fromFrame: number;
9
9
  readonly toFrame: number;
10
10
  readonly rowHeight: number;
11
11
  readonly nodePathInfo: SequenceNodePathInfo;
12
12
  readonly segmentIndex: number;
13
- }>;
13
+ };
14
+ export declare const TimelineKeyframeEasingLine: React.NamedExoticComponent<TimelineKeyframeEasingLineProps>;
15
+ export {};
@@ -72,15 +72,13 @@ const getTimelineKeyframeEasingLineStyle = (selected) => ({
72
72
  outline: selected ? `1px solid ${colors_1.BLUE}` : undefined,
73
73
  });
74
74
  exports.getTimelineKeyframeEasingLineStyle = getTimelineKeyframeEasingLineStyle;
75
- const TimelineKeyframeEasingLineVisual = ({ selected }) => {
75
+ const TimelineKeyframeEasingLineVisualUnmemoized = ({ selected }) => {
76
76
  const lineStyle = (0, react_1.useMemo)(() => (0, exports.getTimelineKeyframeEasingLineStyle)(selected), [selected]);
77
77
  return jsx_runtime_1.jsx("div", { style: lineStyle });
78
78
  };
79
- exports.TimelineKeyframeEasingLineVisual = TimelineKeyframeEasingLineVisual;
80
- const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, nodePathInfo, segmentIndex }) => {
79
+ exports.TimelineKeyframeEasingLineVisual = react_1.default.memo(TimelineKeyframeEasingLineVisualUnmemoized);
80
+ const TimelineKeyframeEasingLineInteraction = ({ fromFrame, toFrame, nodePathInfo, segmentIndex, style }) => {
81
81
  const buttonRef = (0, react_1.useRef)(null);
82
- const videoConfig = (0, remotion_1.useVideoConfig)();
83
- const timelineWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
84
82
  const { selected, onSelect, selectable, selectionItem } = (0, TimelineSelection_1.useTimelineEasingSelection)({
85
83
  nodePathInfo,
86
84
  fromFrame,
@@ -88,6 +86,10 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
88
86
  segmentIndex,
89
87
  });
90
88
  (0, TimelineSelection_1.useTimelineMarqueeSelectableItem)(selectionItem, buttonRef);
89
+ const interactiveStyle = (0, react_1.useMemo)(() => ({
90
+ ...style,
91
+ pointerEvents: selectable ? 'auto' : 'none',
92
+ }), [selectable, style]);
91
93
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
92
94
  const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
93
95
  const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
@@ -120,7 +122,16 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
120
122
  sequencesRef,
121
123
  setPropStatuses,
122
124
  ]);
123
- const contextMenuValues = (0, react_1.useMemo)(() => {
125
+ const getContextMenuItems = (0, react_1.useCallback)((event) => {
126
+ if (!selectable) {
127
+ return false;
128
+ }
129
+ if (!selected) {
130
+ onSelect({
131
+ shiftKey: event.shiftKey,
132
+ toggleKey: event.metaKey || event.ctrlKey,
133
+ });
134
+ }
124
135
  return [
125
136
  {
126
137
  type: 'item',
@@ -147,19 +158,20 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
147
158
  value: preset.id,
148
159
  })),
149
160
  ];
150
- }, [previewServerState.type, updateEasing]);
151
- const onOpenContextMenu = (0, react_1.useCallback)((event) => {
152
- if (!selectable) {
153
- return false;
154
- }
155
- if (!selected) {
156
- onSelect({
157
- shiftKey: event.shiftKey,
158
- toggleKey: event.metaKey || event.ctrlKey,
159
- });
160
- }
161
- return contextMenuValues;
162
- }, [contextMenuValues, onSelect, selectable, selected]);
161
+ }, [onSelect, previewServerState.type, selectable, selected, updateEasing]);
162
+ const onPointerDown = (0, use_timeline_keyframe_drag_1.useTimelineEasingKeyframeDrag)({
163
+ onSelect,
164
+ selectable,
165
+ selected,
166
+ selectionItem,
167
+ });
168
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
169
+ jsx_runtime_1.jsx("button", { ref: buttonRef, [TimelineSelection_1.TIMELINE_MARQUEE_ITEM_ATTR]: true, type: "button", style: interactiveStyle, title: `Easing from frame ${fromFrame} to ${toFrame}`, "aria-label": `Select easing from frame ${fromFrame} to ${toFrame}`, onPointerDown: selectable ? onPointerDown : undefined, children: jsx_runtime_1.jsx(exports.TimelineKeyframeEasingLineVisual, { selected: selected }) }), jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: buttonRef, getItems: getContextMenuItems })
170
+ ] }));
171
+ };
172
+ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, nodePathInfo, segmentIndex }) => {
173
+ const videoConfig = (0, remotion_1.useVideoConfig)();
174
+ const timelineWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
163
175
  const style = (0, react_1.useMemo)(() => {
164
176
  if (timelineWidth === null) {
165
177
  return null;
@@ -174,29 +186,19 @@ const TimelineKeyframeEasingLineUnmemoized = ({ fromFrame, toFrame, rowHeight, n
174
186
  return {
175
187
  ...easingLineButton,
176
188
  left,
177
- pointerEvents: selectable ? 'auto' : 'none',
178
189
  top: rowHeight / 2,
179
190
  width,
180
191
  };
181
192
  }, [
182
193
  fromFrame,
183
194
  rowHeight,
184
- selectable,
185
195
  timelineWidth,
186
196
  toFrame,
187
197
  videoConfig.durationInFrames,
188
198
  ]);
189
- const onPointerDown = (0, use_timeline_keyframe_drag_1.useTimelineEasingKeyframeDrag)({
190
- onSelect,
191
- selectable,
192
- selected,
193
- selectionItem,
194
- });
195
199
  if (style === null) {
196
200
  return null;
197
201
  }
198
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
199
- jsx_runtime_1.jsx("button", { ref: buttonRef, [TimelineSelection_1.TIMELINE_MARQUEE_ITEM_ATTR]: true, type: "button", style: style, title: `Easing from frame ${fromFrame} to ${toFrame}`, "aria-label": `Select easing from frame ${fromFrame} to ${toFrame}`, onPointerDown: selectable ? onPointerDown : undefined, children: jsx_runtime_1.jsx(exports.TimelineKeyframeEasingLineVisual, { selected: selected }) }), jsx_runtime_1.jsx(ContextMenu_1.ContextMenuForTarget, { triggerRef: buttonRef, values: contextMenuValues, onOpen: onOpenContextMenu })
200
- ] }));
202
+ return (jsx_runtime_1.jsx(TimelineKeyframeEasingLineInteraction, { fromFrame: fromFrame, toFrame: toFrame, rowHeight: rowHeight, nodePathInfo: nodePathInfo, segmentIndex: segmentIndex, style: style }));
201
203
  };
202
204
  exports.TimelineKeyframeEasingLine = react_1.default.memo(TimelineKeyframeEasingLineUnmemoized);
@@ -2,4 +2,5 @@ import React from 'react';
2
2
  import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
3
  export declare const TimelineList: React.FC<{
4
4
  readonly timeline: TimelineTrackData[];
5
+ readonly showTimePadding: boolean;
5
6
  }>;
@@ -16,9 +16,8 @@ const TimelineListTrack = ({ nestedTrack }) => {
16
16
  const { track, children, siblingIndex } = nestedTrack;
17
17
  return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { siblingIndex: siblingIndex, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset, children: children.map((child) => (jsx_runtime_1.jsx(TimelineListTrack, { nestedTrack: child }, child.track.sequence.id))) }) }));
18
18
  };
19
- const TimelineList = ({ timeline }) => {
19
+ const TimelineList = ({ timeline, showTimePadding }) => {
20
20
  const nestedTimeline = (0, react_1.useMemo)(() => (0, nest_timeline_tracks_1.nestTimelineTracks)(timeline), [timeline]);
21
- return (jsx_runtime_1.jsxs("div", { style: container, children: [
22
- jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), nestedTimeline.map((nestedTrack) => (jsx_runtime_1.jsx(TimelineListTrack, { nestedTrack: nestedTrack }, nestedTrack.track.sequence.id)))] }));
21
+ return (jsx_runtime_1.jsxs("div", { style: container, children: [showTimePadding ? jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}) : null, nestedTimeline.map((nestedTrack) => (jsx_runtime_1.jsx(TimelineListTrack, { nestedTrack: nestedTrack }, nestedTrack.track.sequence.id)))] }));
23
22
  };
24
23
  exports.TimelineList = TimelineList;
@@ -308,7 +308,7 @@ const TimelineScaleField = ({ field, propStatus, effectiveValue, onSave, onDragV
308
308
  });
309
309
  }, [field.key, linked, scaleLockNodePath, setScaleLockState]);
310
310
  return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
311
- jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false }), jsx_runtime_1.jsx("div", { style: gapStyle }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false }), jsx_runtime_1.jsx(LinkToggle, { linked: linked, onToggle: onToggleLink })
311
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false, allowStepMismatch: true }), jsx_runtime_1.jsx("div", { style: gapStyle }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false, allowStepMismatch: true }), jsx_runtime_1.jsx(LinkToggle, { linked: linked, onToggle: onToggleLink })
312
312
  ] }));
313
313
  };
314
314
  exports.TimelineScaleField = TimelineScaleField;