@remotion/studio 4.0.484 → 4.0.486

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 (288) hide show
  1. package/dist/ResolveCompositionConfigInStudio.js +42 -0
  2. package/dist/components/AssetSelector.js +1 -1
  3. package/dist/components/AssetSelectorItem.js +9 -9
  4. package/dist/components/AudioWaveform.js +3 -3
  5. package/dist/components/Button.js +2 -2
  6. package/dist/components/Canvas.js +28 -0
  7. package/dist/components/CanvasOrLoading.js +1 -1
  8. package/dist/components/CheckboardToggle.js +1 -1
  9. package/dist/components/Checkbox.js +3 -3
  10. package/dist/components/ColorPicker/AlphaSlider.js +4 -3
  11. package/dist/components/ColorPicker/ColorPicker.js +4 -4
  12. package/dist/components/ColorPicker/ColorPickerPopup.js +10 -10
  13. package/dist/components/ColorPicker/HueSlider.js +4 -3
  14. package/dist/components/ColorPicker/SaturationValueArea.js +5 -4
  15. package/dist/components/ColorPicker/checker.d.ts +1 -1
  16. package/dist/components/ColorPicker/checker.js +3 -3
  17. package/dist/components/CompactExplanation.js +3 -3
  18. package/dist/components/CompositionSelector.js +141 -5
  19. package/dist/components/CompositionSelectorItem.d.ts +1 -0
  20. package/dist/components/CompositionSelectorItem.js +103 -11
  21. package/dist/components/ContextMenu.js +75 -1
  22. package/dist/components/CopyButton.js +3 -2
  23. package/dist/components/CurrentAsset.d.ts +3 -1
  24. package/dist/components/CurrentAsset.js +15 -2
  25. package/dist/components/CurrentComposition.js +3 -2
  26. package/dist/components/EffectPickerModal.js +1 -1
  27. package/dist/components/FilePreview.js +2 -1
  28. package/dist/components/FpsCounter.js +3 -2
  29. package/dist/components/FullscreenToggle.js +2 -1
  30. package/dist/components/GlobalKeybindings.js +0 -12
  31. package/dist/components/InlineAction.js +2 -2
  32. package/dist/components/InlineCompositionName.d.ts +7 -0
  33. package/dist/components/InlineCompositionName.js +58 -0
  34. package/dist/components/InlineEditableTitle.d.ts +8 -0
  35. package/dist/components/InlineEditableTitle.js +134 -0
  36. package/dist/components/InspectorInfoHeader.js +2 -2
  37. package/dist/components/InspectorPanel/DefaultInspector.d.ts +1 -0
  38. package/dist/components/InspectorPanel/DefaultInspector.js +2 -2
  39. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +1 -1
  40. package/dist/components/InspectorPanel/KeyframeInspector.js +1 -0
  41. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +17 -30
  42. package/dist/components/InspectorPanel/common.js +2 -2
  43. package/dist/components/InspectorPanel/styles.js +5 -5
  44. package/dist/components/InspectorPanel.d.ts +1 -0
  45. package/dist/components/InspectorPanel.js +2 -2
  46. package/dist/components/InspectorSequenceSection.js +35 -2
  47. package/dist/components/InstallablePackage.js +1 -1
  48. package/dist/components/KeyboardShortcutsExplainer.js +5 -5
  49. package/dist/components/LoopToggle.js +1 -1
  50. package/dist/components/Menu/MenuDivider.js +1 -1
  51. package/dist/components/Menu/MenuItem.js +1 -1
  52. package/dist/components/Menu/MenuSubItem.js +1 -1
  53. package/dist/components/Menu/styles.js +3 -3
  54. package/dist/components/MenuToolbar.js +2 -2
  55. package/dist/components/ModalButton.js +1 -1
  56. package/dist/components/ModalContainer.js +3 -3
  57. package/dist/components/ModalFooter.js +2 -1
  58. package/dist/components/ModalHeader.js +3 -2
  59. package/dist/components/Modals.js +2 -1
  60. package/dist/components/NewComposition/CancelButton.js +4 -3
  61. package/dist/components/NewComposition/CodemodFooter.d.ts +7 -1
  62. package/dist/components/NewComposition/CodemodFooter.js +17 -12
  63. package/dist/components/NewComposition/ComboBox.js +3 -3
  64. package/dist/components/NewComposition/DeleteComposition.js +7 -1
  65. package/dist/components/NewComposition/DeleteFolder.js +7 -1
  66. package/dist/components/NewComposition/DuplicateComposition.js +17 -10
  67. package/dist/components/NewComposition/InputAndValidationContainer.d.ts +3 -0
  68. package/dist/components/NewComposition/InputAndValidationContainer.js +15 -0
  69. package/dist/components/NewComposition/InputDragger.js +11 -3
  70. package/dist/components/NewComposition/MenuContent.js +1 -1
  71. package/dist/components/NewComposition/NewCompDuration.js +7 -6
  72. package/dist/components/NewComposition/NewComposition.d.ts +5 -1
  73. package/dist/components/NewComposition/NewComposition.js +31 -85
  74. package/dist/components/NewComposition/NewFolder.d.ts +5 -0
  75. package/dist/components/NewComposition/NewFolder.js +86 -0
  76. package/dist/components/NewComposition/RemInput.js +3 -3
  77. package/dist/components/NewComposition/RemTextarea.js +1 -1
  78. package/dist/components/NewComposition/RenameComposition.js +13 -14
  79. package/dist/components/NewComposition/RenameFolder.js +9 -2
  80. package/dist/components/NewComposition/RenameStaticFile.js +22 -60
  81. package/dist/components/NewComposition/ValidationMessage.js +10 -2
  82. package/dist/components/NewComposition/use-rename-static-file.d.ts +18 -0
  83. package/dist/components/NewComposition/use-rename-static-file.js +90 -0
  84. package/dist/components/NoRegisterRoot.js +3 -2
  85. package/dist/components/Notifications/ColorDot.js +3 -2
  86. package/dist/components/Notifications/Notification.js +4 -4
  87. package/dist/components/Notifications/NotificationCenter.js +2 -1
  88. package/dist/components/Notifications/ServerDisconnected.js +5 -4
  89. package/dist/components/OptionsPanel.d.ts +0 -3
  90. package/dist/components/OptionsPanel.js +8 -4
  91. package/dist/components/OutlineToggle.js +1 -1
  92. package/dist/components/PlayPause.js +4 -3
  93. package/dist/components/PreviewToolbar.js +1 -1
  94. package/dist/components/QuickSwitcher/AlgoliaCredit.js +2 -1
  95. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  96. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +2 -2
  97. package/dist/components/RefreshCompositionOverlay.js +2 -1
  98. package/dist/components/RenderButton.js +9 -9
  99. package/dist/components/RenderModal/CliCopyButton.js +1 -1
  100. package/dist/components/RenderModal/ClientRenderProgress.js +1 -1
  101. package/dist/components/RenderModal/DataEditor.js +1 -1
  102. package/dist/components/RenderModal/GuiRenderStatus.js +1 -1
  103. package/dist/components/RenderModal/InfoBubble.js +2 -2
  104. package/dist/components/RenderModal/InfoTooltip.js +3 -3
  105. package/dist/components/RenderModal/InlineEyeIcon.js +2 -1
  106. package/dist/components/RenderModal/InlineRemoveButton.js +2 -1
  107. package/dist/components/RenderModal/MultiRangeSlider.js +1 -1
  108. package/dist/components/RenderModal/OptionExplainer.js +2 -2
  109. package/dist/components/RenderModal/RenderModalHr.js +2 -1
  110. package/dist/components/RenderModal/RenderStatusModal.js +2 -1
  111. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +1 -5
  112. package/dist/components/RenderModal/SchemaEditor/SchemaResetButton.js +2 -1
  113. package/dist/components/RenderModal/SchemaEditor/SchemaSeparationLine.js +1 -1
  114. package/dist/components/RenderModal/SchemaEditor/SchemaVerticalGuide.js +2 -1
  115. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +1 -1
  116. package/dist/components/RenderModal/SchemaEditor/ZodErrorMessages.js +1 -1
  117. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +1 -1
  118. package/dist/components/RenderModal/SchemaEditor/create-zod-values.js +2 -1
  119. package/dist/components/RenderModal/ServerRenderModal.js +5 -4
  120. package/dist/components/RenderModal/WarningIndicatorButton.js +4 -6
  121. package/dist/components/RenderModal/WebRenderModal.js +2 -1
  122. package/dist/components/RenderModal/WebRenderModalAudio.js +4 -3
  123. package/dist/components/RenderModal/WebRenderModalLicense.js +2 -2
  124. package/dist/components/RenderModal/WebRenderModalPicture.js +2 -1
  125. package/dist/components/RenderModal/render-modals.js +3 -3
  126. package/dist/components/RenderPreview.js +1 -1
  127. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +2 -1
  128. package/dist/components/RenderQueue/RenderQueueDownloadItem.js +2 -1
  129. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +2 -1
  130. package/dist/components/RenderQueue/RenderQueueItemStatus.js +1 -1
  131. package/dist/components/RenderQueue/RenderQueueOpenInFolder.js +2 -1
  132. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +2 -1
  133. package/dist/components/RenderQueue/RenderQueueRepeat.js +2 -1
  134. package/dist/components/RenderQueue/index.js +1 -1
  135. package/dist/components/RendersTab.js +2 -2
  136. package/dist/components/SegmentedControl.js +3 -3
  137. package/dist/components/SelectedOutlineElement.d.ts +5 -0
  138. package/dist/components/SelectedOutlineElement.js +52 -10
  139. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  140. package/dist/components/SelectedOutlineOverlay.js +16 -4
  141. package/dist/components/SelectedOutlineUvControls.js +5 -5
  142. package/dist/components/SidebarCollapserControls.js +5 -4
  143. package/dist/components/Splitter/SplitterElement.js +2 -1
  144. package/dist/components/StaticFilePreview.js +1 -1
  145. package/dist/components/Tabs/index.js +3 -3
  146. package/dist/components/Tabs/vertical.js +3 -3
  147. package/dist/components/TextViewer.js +2 -1
  148. package/dist/components/TimeValue.js +1 -1
  149. package/dist/components/Timeline/EasingEditorModal.js +8 -8
  150. package/dist/components/Timeline/KeyframeSettingsModal.js +1 -1
  151. package/dist/components/Timeline/LoopedIndicator.js +2 -2
  152. package/dist/components/Timeline/MaxTimelineTracks.js +3 -2
  153. package/dist/components/Timeline/TimelineArrayField.js +6 -5
  154. package/dist/components/Timeline/TimelineColorField.js +2 -1
  155. package/dist/components/Timeline/TimelineDeleteKeybindings.js +34 -1
  156. package/dist/components/Timeline/TimelineEffectItem.js +3 -2
  157. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  158. package/dist/components/Timeline/TimelineExpandArrowButton.js +3 -2
  159. package/dist/components/Timeline/TimelineExpandedRow.js +2 -1
  160. package/dist/components/Timeline/TimelineExpandedSection.js +2 -1
  161. package/dist/components/Timeline/TimelineFieldLabel.js +2 -1
  162. package/dist/components/Timeline/TimelineFontFamilyField.d.ts +11 -0
  163. package/dist/components/Timeline/TimelineFontFamilyField.js +545 -0
  164. package/dist/components/Timeline/TimelineImageInfo.js +2 -1
  165. package/dist/components/Timeline/TimelineInOutPointer.js +2 -1
  166. package/dist/components/Timeline/TimelineInOutPointerHandle.js +4 -5
  167. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -1
  168. package/dist/components/Timeline/TimelineKeyframeControls.js +3 -2
  169. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.js +1 -1
  170. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +1 -1
  171. package/dist/components/Timeline/TimelineLayerEye.js +3 -3
  172. package/dist/components/Timeline/TimelineMediaInfo.js +2 -2
  173. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +8 -0
  174. package/dist/components/Timeline/TimelineRotationField.js +4 -3
  175. package/dist/components/Timeline/TimelineScaleField.js +1 -1
  176. package/dist/components/Timeline/TimelineSchemaField.d.ts +2 -0
  177. package/dist/components/Timeline/TimelineSchemaField.js +47 -7
  178. package/dist/components/Timeline/TimelineScrollable.js +3 -2
  179. package/dist/components/Timeline/TimelineSelection.js +7 -6
  180. package/dist/components/Timeline/TimelineSequence.js +17 -20
  181. package/dist/components/Timeline/TimelineSequenceFrame.js +3 -2
  182. package/dist/components/Timeline/TimelineSequenceItem.js +27 -108
  183. package/dist/components/Timeline/TimelineSequenceName.js +3 -2
  184. package/dist/components/Timeline/TimelineSequencePropItem.js +8 -4
  185. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +20 -1
  186. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +128 -11
  187. package/dist/components/Timeline/TimelineSlider.js +2 -1
  188. package/dist/components/Timeline/TimelineSliderHandle.js +2 -1
  189. package/dist/components/Timeline/TimelineTextContentField.d.ts +12 -0
  190. package/dist/components/Timeline/TimelineTextContentField.js +100 -0
  191. package/dist/components/Timeline/TimelineTimeIndicators.js +1 -1
  192. package/dist/components/Timeline/TimelineVideoInfo.js +2 -1
  193. package/dist/components/Timeline/TimelineWidthProvider.js +18 -3
  194. package/dist/components/Timeline/TimelineZoomControls.js +4 -3
  195. package/dist/components/Timeline/call-move-keyframe.d.ts +5 -0
  196. package/dist/components/Timeline/call-move-keyframe.js +14 -3
  197. package/dist/components/Timeline/focus-inspector-field.d.ts +16 -0
  198. package/dist/components/Timeline/focus-inspector-field.js +49 -0
  199. package/dist/components/Timeline/google-fonts-list.d.ts +6 -0
  200. package/dist/components/Timeline/google-fonts-list.js +1512 -0
  201. package/dist/components/Timeline/save-sequence-prop.d.ts +8 -1
  202. package/dist/components/Timeline/save-sequence-prop.js +63 -19
  203. package/dist/components/Timeline/split-selected-timeline-item.d.ts +38 -0
  204. package/dist/components/Timeline/split-selected-timeline-item.js +156 -0
  205. package/dist/components/Timeline/timeline-field-display-utils.js +2 -0
  206. package/dist/components/Timeline/timeline-rotation-field-utils.d.ts +5 -0
  207. package/dist/components/Timeline/timeline-rotation-field-utils.js +16 -0
  208. package/dist/components/Timeline/timeline-scroll-logic.js +5 -2
  209. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +1 -0
  210. package/dist/components/Timeline/use-rename-sequence.d.ts +30 -0
  211. package/dist/components/Timeline/use-rename-sequence.js +115 -0
  212. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  213. package/dist/components/Timeline/use-timeline-expanded-tree.js +3 -1
  214. package/dist/components/Timeline/use-timeline-height.js +1 -0
  215. package/dist/components/TimelineInOutToggle.js +1 -1
  216. package/dist/components/UpdateCheck.js +2 -2
  217. package/dist/components/UpdateModal/OpenIssueButton.js +1 -1
  218. package/dist/components/VisualControls/ClickableFileName.js +2 -2
  219. package/dist/components/composition-menu-items.js +3 -0
  220. package/dist/components/effect-drag-and-drop.js +1 -0
  221. package/dist/components/folder-menu-items.js +20 -0
  222. package/dist/components/import-assets.d.ts +7 -1
  223. package/dist/components/import-assets.js +55 -1
  224. package/dist/components/options-sidebar-tabs.d.ts +4 -0
  225. package/dist/components/options-sidebar-tabs.js +5 -0
  226. package/dist/components/selected-outline-measurement.js +2 -1
  227. package/dist/components/selected-outline-types.d.ts +6 -1
  228. package/dist/error-overlay/remotion-overlay/CalculateMetadataErrorExplainer.js +2 -2
  229. package/dist/error-overlay/remotion-overlay/CodeFrame.js +7 -5
  230. package/dist/error-overlay/remotion-overlay/CompositionIdListItem.js +2 -2
  231. package/dist/error-overlay/remotion-overlay/DismissButton.js +3 -2
  232. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +3 -2
  233. package/dist/error-overlay/remotion-overlay/ErrorMessage.js +4 -4
  234. package/dist/error-overlay/remotion-overlay/HelpLink.js +1 -1
  235. package/dist/error-overlay/remotion-overlay/MediaPlaybackErrorExplainer.js +4 -4
  236. package/dist/error-overlay/remotion-overlay/Overlay.js +3 -2
  237. package/dist/error-overlay/remotion-overlay/StackFrame.js +4 -3
  238. package/dist/error-overlay/remotion-overlay/Symbolicating.js +2 -1
  239. package/dist/error-overlay/remotion-overlay/carets.js +3 -2
  240. package/dist/esm/{chunk-9erwh79m.js → chunk-975rp13y.js} +11165 -7032
  241. package/dist/esm/chunk-jefhcs5z.js +164 -0
  242. package/dist/esm/internals.mjs +11166 -6999
  243. package/dist/esm/previewEntry.mjs +10697 -6526
  244. package/dist/esm/renderEntry.mjs +8 -5
  245. package/dist/helpers/checkerboard-background.js +4 -12
  246. package/dist/helpers/colors.d.ts +99 -7
  247. package/dist/helpers/colors.js +118 -10
  248. package/dist/helpers/inject-css.js +85 -83
  249. package/dist/helpers/render-codec-label.d.ts +1 -1
  250. package/dist/helpers/timeline-layout.d.ts +7 -4
  251. package/dist/helpers/timeline-layout.js +3 -1
  252. package/dist/helpers/use-create-composition.d.ts +35 -0
  253. package/dist/helpers/use-create-composition.js +111 -0
  254. package/dist/helpers/use-menu-structure.js +31 -3
  255. package/dist/helpers/use-rename-composition.d.ts +16 -0
  256. package/dist/helpers/use-rename-composition.js +49 -0
  257. package/dist/helpers/validate-folder-rename.js +2 -10
  258. package/dist/helpers/validate-new-folder-name.d.ts +5 -0
  259. package/dist/helpers/validate-new-folder-name.js +16 -0
  260. package/dist/hot-middleware-client/client.js +3 -2
  261. package/dist/icons/Checkmark.js +2 -1
  262. package/dist/icons/audio.js +2 -1
  263. package/dist/icons/caret.js +2 -2
  264. package/dist/icons/certificate.js +2 -1
  265. package/dist/icons/data.js +2 -1
  266. package/dist/icons/eyedropper.js +2 -1
  267. package/dist/icons/file.js +2 -1
  268. package/dist/icons/frame.js +2 -1
  269. package/dist/icons/gear.js +2 -1
  270. package/dist/icons/gif.js +2 -1
  271. package/dist/icons/jump-to-start.js +2 -1
  272. package/dist/icons/keys.js +4 -3
  273. package/dist/icons/media-volume.js +1 -1
  274. package/dist/icons/minus.js +2 -1
  275. package/dist/icons/pause.js +2 -1
  276. package/dist/icons/play.js +2 -1
  277. package/dist/icons/redo.js +2 -1
  278. package/dist/icons/step-back.js +2 -1
  279. package/dist/icons/step-forward.js +2 -1
  280. package/dist/icons/undo.js +2 -1
  281. package/dist/previewEntry.js +2 -1
  282. package/dist/renderEntry.js +4 -3
  283. package/dist/state/modals.d.ts +7 -0
  284. package/dist/state/timeline-zoom.js +17 -14
  285. package/dist/state/z-index.d.ts +1 -0
  286. package/dist/state/z-index.js +11 -2
  287. package/package.json +12 -12
  288. package/dist/esm/chunk-6jf1natv.js +0 -25
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CompositionSelector = exports.useCompositionNavigation = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const studio_shared_1 = require("@remotion/studio-shared");
5
6
  const react_1 = require("react");
6
7
  const remotion_1 = require("remotion");
7
8
  const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
@@ -14,6 +15,8 @@ const modals_1 = require("../state/modals");
14
15
  const z_index_1 = require("../state/z-index");
15
16
  const CompositionSelectorItem_1 = require("./CompositionSelectorItem");
16
17
  const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
18
+ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
19
+ const actions_1 = require("./RenderQueue/actions");
17
20
  const useCompositionNavigation = () => {
18
21
  const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
19
22
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
@@ -60,10 +63,10 @@ const container = {
60
63
  };
61
64
  const quickSwitcherArea = {
62
65
  padding: '4px 12px',
63
- borderBottom: `1px solid ${colors_1.BORDER_COLOR}`,
66
+ borderBottom: `1px solid ${colors_1.BLACK_HEX}`,
64
67
  };
65
68
  const quickSwitcherTrigger = {
66
- backgroundColor: 'rgba(255, 255, 255, 0.06)',
69
+ backgroundColor: colors_1.WHITE_ALPHA_06,
67
70
  borderRadius: 5,
68
71
  padding: '4px 10px',
69
72
  color: colors_1.LIGHT_TEXT,
@@ -80,10 +83,34 @@ const shortcutLabel = {
80
83
  fontSize: 11,
81
84
  opacity: 0.6,
82
85
  };
86
+ const autoScrollThreshold = 70;
87
+ const maxAutoScrollSpeed = 18;
88
+ const getAutoScrollSpeed = ({ clientY, element, }) => {
89
+ const { top, bottom } = element.getBoundingClientRect();
90
+ const threshold = Math.min(autoScrollThreshold, element.clientHeight / 2);
91
+ if (threshold <= 0) {
92
+ return 0;
93
+ }
94
+ const distanceToTop = clientY - top;
95
+ const distanceToBottom = bottom - clientY;
96
+ if (distanceToTop < threshold) {
97
+ const progress = Math.min(1, (threshold - distanceToTop) / threshold);
98
+ return -Math.ceil(progress * maxAutoScrollSpeed);
99
+ }
100
+ if (distanceToBottom < threshold) {
101
+ const progress = Math.min(1, (threshold - distanceToBottom) / threshold);
102
+ return Math.ceil(progress * maxAutoScrollSpeed);
103
+ }
104
+ return 0;
105
+ };
83
106
  const CompositionSelector = () => {
84
107
  const { compositions, canvasContent, folders } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
85
108
  const { foldersExpanded } = (0, react_1.useContext)(persist_open_folders_1.ExpandedFoldersContext);
86
109
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
110
+ const [rootDragHovered, setRootDragHovered] = (0, react_1.useState)(false);
111
+ const listRef = (0, react_1.useRef)(null);
112
+ const autoScrollAnimation = (0, react_1.useRef)(null);
113
+ const autoScrollSpeed = (0, react_1.useRef)(0);
87
114
  const { tabIndex } = (0, z_index_1.useZIndex)();
88
115
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
89
116
  const sortedCompositions = (0, react_1.useMemo)(() => {
@@ -99,8 +126,9 @@ const CompositionSelector = () => {
99
126
  return {
100
127
  flex: 1,
101
128
  overflowY: 'auto',
129
+ backgroundColor: rootDragHovered ? colors_1.WHITE_ALPHA_12 : colors_1.BACKGROUND,
102
130
  };
103
- }, []);
131
+ }, [rootDragHovered]);
104
132
  const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
105
133
  var _a;
106
134
  (_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.toggleFolder(folderName, parentName);
@@ -112,11 +140,119 @@ const CompositionSelector = () => {
112
140
  invocationTimestamp: Date.now(),
113
141
  });
114
142
  }, [setSelectedModal]);
143
+ const clearRootDragHover = (0, react_1.useCallback)(() => {
144
+ setRootDragHovered(false);
145
+ }, []);
146
+ const stopCompositionListAutoScroll = (0, react_1.useCallback)(() => {
147
+ autoScrollSpeed.current = 0;
148
+ if (autoScrollAnimation.current !== null) {
149
+ cancelAnimationFrame(autoScrollAnimation.current);
150
+ autoScrollAnimation.current = null;
151
+ }
152
+ }, []);
153
+ const runCompositionListAutoScroll = (0, react_1.useCallback)(() => {
154
+ const listElement = listRef.current;
155
+ const speed = autoScrollSpeed.current;
156
+ if (listElement === null || speed === 0) {
157
+ autoScrollAnimation.current = null;
158
+ return;
159
+ }
160
+ const scrollTopBefore = listElement.scrollTop;
161
+ listElement.scrollTop += speed;
162
+ if (listElement.scrollTop === scrollTopBefore) {
163
+ autoScrollAnimation.current = null;
164
+ return;
165
+ }
166
+ autoScrollAnimation.current = requestAnimationFrame(runCompositionListAutoScroll);
167
+ }, []);
168
+ const setCompositionListAutoScrollSpeed = (0, react_1.useCallback)((speed) => {
169
+ if (speed === 0) {
170
+ stopCompositionListAutoScroll();
171
+ return;
172
+ }
173
+ autoScrollSpeed.current = speed;
174
+ if (autoScrollAnimation.current === null) {
175
+ autoScrollAnimation.current = requestAnimationFrame(runCompositionListAutoScroll);
176
+ }
177
+ }, [runCompositionListAutoScroll, stopCompositionListAutoScroll]);
178
+ const onCompositionListDragOverCapture = (0, react_1.useCallback)((event) => {
179
+ if (window.remotion_isReadOnlyStudio ||
180
+ !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
181
+ stopCompositionListAutoScroll();
182
+ return;
183
+ }
184
+ const listElement = listRef.current;
185
+ if (listElement === null) {
186
+ stopCompositionListAutoScroll();
187
+ return;
188
+ }
189
+ setCompositionListAutoScrollSpeed(getAutoScrollSpeed({ clientY: event.clientY, element: listElement }));
190
+ }, [setCompositionListAutoScrollSpeed, stopCompositionListAutoScroll]);
191
+ (0, react_1.useEffect)(() => {
192
+ return stopCompositionListAutoScroll;
193
+ }, [stopCompositionListAutoScroll]);
194
+ const onRootDragOver = (0, react_1.useCallback)((event) => {
195
+ if (window.remotion_isReadOnlyStudio ||
196
+ !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
197
+ return;
198
+ }
199
+ event.preventDefault();
200
+ event.dataTransfer.dropEffect = 'move';
201
+ setRootDragHovered(true);
202
+ }, []);
203
+ const onRootDragLeave = (0, react_1.useCallback)((event) => {
204
+ const { relatedTarget } = event;
205
+ if (relatedTarget instanceof Node &&
206
+ event.currentTarget.contains(relatedTarget)) {
207
+ return;
208
+ }
209
+ stopCompositionListAutoScroll();
210
+ setRootDragHovered(false);
211
+ }, [stopCompositionListAutoScroll]);
212
+ const onRootDrop = (0, react_1.useCallback)(async (event) => {
213
+ if (window.remotion_isReadOnlyStudio) {
214
+ return;
215
+ }
216
+ const raw = event.dataTransfer.getData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
217
+ const parsed = raw ? (0, studio_shared_1.parseCompositionDragData)(raw) : null;
218
+ if (parsed === null) {
219
+ return;
220
+ }
221
+ event.preventDefault();
222
+ event.stopPropagation();
223
+ stopCompositionListAutoScroll();
224
+ setRootDragHovered(false);
225
+ const composition = compositions.find((c) => c.id === parsed.compositionId);
226
+ if (!composition || composition.folderName === null) {
227
+ return;
228
+ }
229
+ const notification = (0, NotificationCenter_1.showNotification)(`Moving ${parsed.compositionId}...`, null);
230
+ const controller = new AbortController();
231
+ try {
232
+ const result = await (0, actions_1.applyCodemod)({
233
+ codemod: {
234
+ type: 'move-composition-to-folder',
235
+ idToMove: parsed.compositionId,
236
+ folderName: null,
237
+ parentName: null,
238
+ },
239
+ dryRun: false,
240
+ signal: controller.signal,
241
+ symbolicatedStack: null,
242
+ });
243
+ notification.replaceContent(result.success
244
+ ? `Moved ${parsed.compositionId} outside of folder`
245
+ : result.reason, result.success ? 2000 : 4000);
246
+ }
247
+ catch (err) {
248
+ notification.replaceContent(err instanceof Error ? err.message : String(err), 4000);
249
+ }
250
+ }, [compositions, stopCompositionListAutoScroll]);
115
251
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
116
- jsx_runtime_1.jsx("div", { style: quickSwitcherArea, children: jsx_runtime_1.jsxs("button", { type: "button", style: quickSwitcherTrigger, onClick: openQuickSwitcher, tabIndex: tabIndex, children: ["Search...", (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : (jsx_runtime_1.jsxs("span", { style: shortcutLabel, children: [ShortcutHint_1.cmdOrCtrlCharacter, "+K"] }))] }) }), jsx_runtime_1.jsx("div", { className: "__remotion-vertical-scrollbar", style: list, children: items.map((c) => {
252
+ jsx_runtime_1.jsx("div", { style: quickSwitcherArea, children: jsx_runtime_1.jsxs("button", { type: "button", style: quickSwitcherTrigger, onClick: openQuickSwitcher, tabIndex: tabIndex, children: ["Search...", (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : (jsx_runtime_1.jsxs("span", { style: shortcutLabel, children: [ShortcutHint_1.cmdOrCtrlCharacter, "+K"] }))] }) }), jsx_runtime_1.jsx("div", { ref: listRef, className: "__remotion-vertical-scrollbar", style: list, onDragOverCapture: onCompositionListDragOverCapture, onDragEndCapture: stopCompositionListAutoScroll, onDragOver: onRootDragOver, onDragLeave: onRootDragLeave, onDropCapture: stopCompositionListAutoScroll, onDrop: onRootDrop, children: items.map((c) => {
117
253
  return (jsx_runtime_1.jsx(CompositionSelectorItem_1.CompositionSelectorItem, { level: 0, currentComposition: canvasContent && canvasContent.type === 'composition'
118
254
  ? canvasContent.compositionId
119
- : null, selectComposition: selectComposition, toggleFolder: toggleFolder, tabIndex: tabIndex, item: c }, c.key + c.type));
255
+ : null, selectComposition: selectComposition, toggleFolder: toggleFolder, clearRootDragHover: clearRootDragHover, tabIndex: tabIndex, item: c }, c.key + c.type));
120
256
  }) })
121
257
  ] }));
122
258
  };
@@ -19,5 +19,6 @@ export declare const CompositionSelectorItem: React.FC<{
19
19
  readonly tabIndex: number;
20
20
  readonly selectComposition: (c: _InternalTypes['AnyComposition'], push: boolean) => void;
21
21
  readonly toggleFolder: (folderName: string, parentName: string | null) => void;
22
+ readonly clearRootDragHover: () => void;
22
23
  readonly level: number;
23
24
  }>;
@@ -2,9 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CompositionSelectorItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const studio_shared_1 = require("@remotion/studio-shared");
5
6
  const react_1 = require("react");
6
7
  const client_id_1 = require("../helpers/client-id");
7
8
  const colors_1 = require("../helpers/colors");
9
+ const get_folder_id_1 = require("../helpers/get-folder-id");
8
10
  const is_composition_still_1 = require("../helpers/is-composition-still");
9
11
  const noop_1 = require("../helpers/noop");
10
12
  const sidebar_scroll_into_view_1 = require("../helpers/sidebar-scroll-into-view");
@@ -17,6 +19,8 @@ const CompositionContextButton_1 = require("./CompositionContextButton");
17
19
  const ContextMenu_1 = require("./ContextMenu");
18
20
  const folder_menu_items_1 = require("./folder-menu-items");
19
21
  const layout_1 = require("./layout");
22
+ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
23
+ const actions_1 = require("./RenderQueue/actions");
20
24
  const SidebarRenderButton_1 = require("./SidebarRenderButton");
21
25
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
22
26
  const COMPOSITION_ITEM_HEIGHT = 32;
@@ -52,7 +56,7 @@ const iconStyle = {
52
56
  height: 18,
53
57
  flexShrink: 0,
54
58
  };
55
- const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, selectComposition, toggleFolder, }) => {
59
+ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, selectComposition, toggleFolder, clearRootDragHover, }) => {
56
60
  const selected = (0, react_1.useMemo)(() => {
57
61
  if (item.type === 'composition') {
58
62
  return currentComposition === item.composition.id;
@@ -66,6 +70,7 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
66
70
  const onPointerLeave = (0, react_1.useCallback)(() => {
67
71
  setHovered(false);
68
72
  }, []);
73
+ const [dragHovered, setDragHovered] = (0, react_1.useState)(false);
69
74
  const compositionRowRef = (0, react_1.useRef)(null);
70
75
  const compositionId = item.type === 'composition' ? item.composition.id : null;
71
76
  (0, react_1.useLayoutEffect)(() => {
@@ -81,14 +86,16 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
81
86
  const style = (0, react_1.useMemo)(() => {
82
87
  return {
83
88
  ...itemStyle,
84
- backgroundColor: (0, colors_1.getBackgroundFromHoverState)({ hovered, selected }),
89
+ backgroundColor: dragHovered
90
+ ? colors_1.WHITE_ALPHA_12
91
+ : (0, colors_1.getBackgroundFromHoverState)({ hovered, selected }),
85
92
  paddingLeft: 12 + level * 8,
86
93
  };
87
- }, [hovered, level, selected]);
94
+ }, [dragHovered, hovered, level, selected]);
88
95
  const label = (0, react_1.useMemo)(() => {
89
96
  return {
90
97
  ...labelStyle,
91
- color: selected || hovered ? 'white' : colors_1.LIGHT_TEXT,
98
+ color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT,
92
99
  };
93
100
  }, [hovered, selected]);
94
101
  const onClick = (0, react_1.useCallback)((evt) => {
@@ -130,16 +137,101 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
130
137
  readOnlyStudio: window.remotion_isReadOnlyStudio,
131
138
  });
132
139
  }, [connectionStatus, item, resolvedLocation, setSelectedModal]);
140
+ const onCompositionDragStart = (0, react_1.useCallback)((event) => {
141
+ var _a;
142
+ if (item.type !== 'composition' || window.remotion_isReadOnlyStudio) {
143
+ event.preventDefault();
144
+ return;
145
+ }
146
+ event.dataTransfer.effectAllowed = 'copyMove';
147
+ event.dataTransfer.setData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE, JSON.stringify((0, studio_shared_1.makeCompositionDragData)({
148
+ compositionFile: (_a = resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source) !== null && _a !== void 0 ? _a : null,
149
+ compositionId: item.composition.id,
150
+ })));
151
+ }, [item, resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source]);
152
+ const onFolderDragOver = (0, react_1.useCallback)((event) => {
153
+ if (item.type !== 'folder' ||
154
+ window.remotion_isReadOnlyStudio ||
155
+ !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
156
+ return;
157
+ }
158
+ event.preventDefault();
159
+ event.stopPropagation();
160
+ event.dataTransfer.dropEffect = 'move';
161
+ clearRootDragHover();
162
+ setDragHovered(true);
163
+ }, [clearRootDragHover, item]);
164
+ const onFolderDragLeave = (0, react_1.useCallback)(() => {
165
+ setDragHovered(false);
166
+ }, []);
167
+ const onFolderChildListDragOver = (0, react_1.useCallback)((event) => {
168
+ if (item.type !== 'folder' ||
169
+ window.remotion_isReadOnlyStudio ||
170
+ !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
171
+ return;
172
+ }
173
+ event.preventDefault();
174
+ event.stopPropagation();
175
+ event.dataTransfer.dropEffect = 'move';
176
+ clearRootDragHover();
177
+ }, [clearRootDragHover, item]);
178
+ const onFolderDrop = (0, react_1.useCallback)(async (event) => {
179
+ if (item.type !== 'folder' || window.remotion_isReadOnlyStudio) {
180
+ return;
181
+ }
182
+ const raw = event.dataTransfer.getData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
183
+ const parsed = raw ? (0, studio_shared_1.parseCompositionDragData)(raw) : null;
184
+ if (parsed === null) {
185
+ return;
186
+ }
187
+ event.preventDefault();
188
+ event.stopPropagation();
189
+ clearRootDragHover();
190
+ setDragHovered(false);
191
+ const isAlreadyDirectChild = item.items.some((child) => {
192
+ return (child.type === 'composition' &&
193
+ child.composition.id === parsed.compositionId);
194
+ });
195
+ if (isAlreadyDirectChild) {
196
+ return;
197
+ }
198
+ const folderId = (0, get_folder_id_1.getFolderId)({
199
+ folderName: item.folderName,
200
+ parentName: item.parentName,
201
+ });
202
+ const notification = (0, NotificationCenter_1.showNotification)(`Moving ${parsed.compositionId}...`, null);
203
+ const controller = new AbortController();
204
+ try {
205
+ const result = await (0, actions_1.applyCodemod)({
206
+ codemod: {
207
+ type: 'move-composition-to-folder',
208
+ idToMove: parsed.compositionId,
209
+ folderName: item.folderName,
210
+ parentName: item.parentName,
211
+ },
212
+ dryRun: false,
213
+ signal: controller.signal,
214
+ symbolicatedStack: null,
215
+ });
216
+ notification.replaceContent(result.success
217
+ ? `Moved ${parsed.compositionId} to ${folderId}`
218
+ : result.reason, result.success ? 2000 : 4000);
219
+ if (result.success && !item.expanded) {
220
+ toggleFolder(item.folderName, item.parentName);
221
+ }
222
+ }
223
+ catch (err) {
224
+ notification.replaceContent(err instanceof Error ? err.message : String(err), 4000);
225
+ }
226
+ }, [clearRootDragHover, item, toggleFolder]);
133
227
  if (item.type === 'folder') {
134
228
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
135
- jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenu, onOpen: null, children: jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("div", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyDown: onKeyDown, title: item.folderName, role: "button", children: [item.expanded ? (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { style: iconStyle, color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT })) : (jsx_runtime_1.jsx(folder_1.CollapsedFolderIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.folderName }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered })
136
- ] }) }) }), item.expanded
137
- ? item.items.map((childItem) => {
138
- return (jsx_runtime_1.jsx(exports.CompositionSelectorItem, { currentComposition: currentComposition, selectComposition: selectComposition, item: childItem, tabIndex: tabIndex, level: level + 1, toggleFolder: toggleFolder }, childItem.key + childItem.type));
139
- })
140
- : null] }));
229
+ jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenu, onOpen: null, children: jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("div", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyDown: onKeyDown, onDragOver: onFolderDragOver, onDragLeave: onFolderDragLeave, onDrop: onFolderDrop, title: item.folderName, role: "button", children: [item.expanded ? (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { style: iconStyle, color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT })) : (jsx_runtime_1.jsx(folder_1.CollapsedFolderIcon, { color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.folderName }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered })
230
+ ] }) }) }), item.expanded ? (jsx_runtime_1.jsx("div", { onDragOver: onFolderChildListDragOver, onDrop: onFolderDrop, children: item.items.map((childItem) => {
231
+ return (jsx_runtime_1.jsx(exports.CompositionSelectorItem, { currentComposition: currentComposition, selectComposition: selectComposition, item: childItem, tabIndex: tabIndex, level: level + 1, toggleFolder: toggleFolder, clearRootDragHover: clearRootDragHover }, childItem.key + childItem.type));
232
+ }) })) : null] }));
141
233
  }
142
- return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenu, onOpen: null, children: jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("a", { ref: compositionRowRef, style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyDown: onKeyDown, type: "button", title: item.composition.id, className: "__remotion-composition", "data-compname": item.composition.id, children: [(0, is_composition_still_1.isCompositionStill)(item.composition) ? (jsx_runtime_1.jsx(still_1.StillIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : (jsx_runtime_1.jsx(video_1.FilmIcon, { color: hovered || selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.composition.id }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered }), jsx_runtime_1.jsx(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition })
234
+ return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenu, onOpen: null, children: jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("a", { ref: compositionRowRef, style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyDown: onKeyDown, draggable: !window.remotion_isReadOnlyStudio, onDragStart: onCompositionDragStart, type: "button", title: item.composition.id, className: "__remotion-composition", "data-compname": item.composition.id, children: [(0, is_composition_still_1.isCompositionStill)(item.composition) ? (jsx_runtime_1.jsx(still_1.StillIcon, { color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })) : (jsx_runtime_1.jsx(video_1.FilmIcon, { color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.composition.id }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered }), jsx_runtime_1.jsx(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition })
143
235
  ] }) }) }));
144
236
  };
145
237
  exports.CompositionSelectorItem = CompositionSelectorItem;
@@ -47,7 +47,25 @@ const z_index_1 = require("../state/z-index");
47
47
  const portals_1 = require("./Menu/portals");
48
48
  const styles_1 = require("./Menu/styles");
49
49
  const MenuContent_1 = require("./NewComposition/MenuContent");
50
+ const CONTEXT_MENU_Z_INDEX = 1001;
51
+ const contextMenuFullScreenOverlay = {
52
+ ...styles_1.fullScreenOverlay,
53
+ pointerEvents: 'none',
54
+ zIndex: CONTEXT_MENU_Z_INDEX,
55
+ };
56
+ const contextMenuOuterPortal = {
57
+ ...styles_1.outerPortal,
58
+ pointerEvents: 'auto',
59
+ };
60
+ const contextMenuOpenedEvent = 'remotion-context-menu-opened';
61
+ let nextContextMenuId = 0;
62
+ const notifyContextMenuOpened = (id) => {
63
+ window.dispatchEvent(new CustomEvent(contextMenuOpenedEvent, {
64
+ detail: id,
65
+ }));
66
+ };
50
67
  const ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values }) => {
68
+ const menuRef = (0, react_1.useRef)(null);
51
69
  const size = player_1.PlayerInternals.useElementSize(sizeSource, {
52
70
  triggerOnWindowResize: true,
53
71
  shouldApplyCssTransforms: true,
@@ -103,6 +121,34 @@ const ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values }
103
121
  spaceToTop,
104
122
  spaceToBottom,
105
123
  ]);
124
+ (0, react_1.useEffect)(() => {
125
+ const preventNativeContextMenu = (event) => {
126
+ event.preventDefault();
127
+ };
128
+ window.addEventListener('contextmenu', preventNativeContextMenu, true);
129
+ return () => {
130
+ window.removeEventListener('contextmenu', preventNativeContextMenu, true);
131
+ };
132
+ }, []);
133
+ (0, react_1.useEffect)(() => {
134
+ const dismissWithoutClickThrough = (event) => {
135
+ var _a;
136
+ if (event.button !== 0) {
137
+ return;
138
+ }
139
+ if ((_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target)) {
140
+ return;
141
+ }
142
+ event.preventDefault();
143
+ event.stopPropagation();
144
+ event.stopImmediatePropagation();
145
+ onHide();
146
+ };
147
+ window.addEventListener('pointerdown', dismissWithoutClickThrough, true);
148
+ return () => {
149
+ window.removeEventListener('pointerdown', dismissWithoutClickThrough, true);
150
+ };
151
+ }, [onHide]);
106
152
  // Prevent deselection of a selected item
107
153
  const onMenuPointerDown = (0, react_1.useCallback)((e) => {
108
154
  e.stopPropagation();
@@ -110,10 +156,11 @@ const ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values }
110
156
  if (!portalStyle) {
111
157
  return null;
112
158
  }
113
- return react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: jsx_runtime_1.jsx("div", { style: portalStyle, onPointerDown: onMenuPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex));
159
+ return react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: contextMenuFullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: contextMenuOuterPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, outsideClickButton: "primary", children: jsx_runtime_1.jsx("div", { ref: menuRef, style: portalStyle, onPointerDown: onMenuPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: false, topItemCanBeUnselected: false, fixedHeight: null }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex));
114
160
  };
115
161
  exports.ContextMenu = react_1.default.forwardRef(({ children, values, onOpen, style = undefined, className = undefined, onPointerDown = undefined, }, forwardedRef) => {
116
162
  const ref = (0, react_1.useRef)(null);
163
+ const idRef = (0, react_1.useRef)(nextContextMenuId++);
117
164
  const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
118
165
  const { currentZIndex } = (0, z_index_1.useZIndex)();
119
166
  const setRef = (0, react_1.useCallback)((node) => {
@@ -137,6 +184,7 @@ exports.ContextMenu = react_1.default.forwardRef(({ children, values, onOpen, st
137
184
  if ((onOpen === null || onOpen === void 0 ? void 0 : onOpen()) === false) {
138
185
  return false;
139
186
  }
187
+ notifyContextMenuOpened(idRef.current);
140
188
  setOpened({ type: 'open', left: e.clientX, top: e.clientY });
141
189
  return false;
142
190
  };
@@ -148,11 +196,24 @@ exports.ContextMenu = react_1.default.forwardRef(({ children, values, onOpen, st
148
196
  const onHide = (0, react_1.useCallback)(() => {
149
197
  setOpened({ type: 'not-open' });
150
198
  }, []);
199
+ (0, react_1.useEffect)(() => {
200
+ const onOtherContextMenuOpened = (event) => {
201
+ if (event.detail === idRef.current) {
202
+ return;
203
+ }
204
+ onHide();
205
+ };
206
+ window.addEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
207
+ return () => {
208
+ window.removeEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
209
+ };
210
+ }, [onHide]);
151
211
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
152
212
  jsx_runtime_1.jsx("div", { ref: setRef, onContextMenu: () => false, style: style, className: className, onPointerDown: onPointerDown, children: children }), opened.type === 'open' ? (jsx_runtime_1.jsx(ContextMenuPortal, { sizeSource: ref, currentZIndex: currentZIndex, onHide: onHide, opened: opened, values: values })) : null] }));
153
213
  });
154
214
  exports.ContextMenu.displayName = 'ContextMenu';
155
215
  const ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
216
+ const idRef = (0, react_1.useRef)(nextContextMenuId++);
156
217
  const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
157
218
  const [openedValues, setOpenedValues] = (0, react_1.useState)(values);
158
219
  const [body, setBody] = (0, react_1.useState)(null);
@@ -179,6 +240,7 @@ const ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
179
240
  if (nextValues.length === 0) {
180
241
  return false;
181
242
  }
243
+ notifyContextMenuOpened(idRef.current);
182
244
  setOpenedValues(nextValues);
183
245
  setOpened({ type: 'open', left: e.clientX, top: e.clientY });
184
246
  return false;
@@ -191,6 +253,18 @@ const ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
191
253
  const onHide = (0, react_1.useCallback)(() => {
192
254
  setOpened({ type: 'not-open' });
193
255
  }, []);
256
+ (0, react_1.useEffect)(() => {
257
+ const onOtherContextMenuOpened = (event) => {
258
+ if (event.detail === idRef.current) {
259
+ return;
260
+ }
261
+ onHide();
262
+ };
263
+ window.addEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
264
+ return () => {
265
+ window.removeEventListener(contextMenuOpenedEvent, onOtherContextMenuOpened);
266
+ };
267
+ }, [onHide]);
194
268
  return opened.type === 'open' ? (jsx_runtime_1.jsx(ContextMenuPortal, { sizeSource: body, currentZIndex: currentZIndex, onHide: onHide, opened: opened, values: [...openedValues] })) : null;
195
269
  };
196
270
  exports.ContextMenuForTarget = ContextMenuForTarget;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CopyButton = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const colors_1 = require("../helpers/colors");
6
7
  const copy_text_1 = require("../helpers/copy-text");
7
8
  const Button_1 = require("./Button");
8
9
  const layout_1 = require("./layout");
@@ -10,13 +11,13 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
10
11
  const iconStyle = {
11
12
  width: 16,
12
13
  height: 16,
13
- color: 'white',
14
+ color: colors_1.WHITE,
14
15
  };
15
16
  const buttonContainerStyle = {
16
17
  display: 'flex',
17
18
  minWidth: '114px',
18
19
  };
19
- const copyIcon = (jsx_runtime_1.jsx("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "far", "data-icon": "clipboard", className: "svg-inline--fa fa-clipboard fa-w-12", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 384 512", style: iconStyle, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z" }) }));
20
+ const copyIcon = (jsx_runtime_1.jsx("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "far", "data-icon": "clipboard", className: "svg-inline--fa fa-clipboard fa-w-12", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 384 512", style: iconStyle, children: jsx_runtime_1.jsx("path", { fill: colors_1.CURRENT_COLOR, d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z" }) }));
20
21
  const labelStyle = {
21
22
  fontSize: 14,
22
23
  };
@@ -3,4 +3,6 @@ import type { MediaMetadata } from '../helpers/use-media-metadata';
3
3
  export declare const CURRENT_ASSET_HEIGHT = 84;
4
4
  export declare const getCurrentAssetMetadataSource: (assetName: string | null) => string | null;
5
5
  export declare const getCurrentAssetMediaDetailLines: (mediaMetadata: MediaMetadata) => string[];
6
- export declare const CurrentAsset: React.FC;
6
+ export declare const CurrentAsset: React.FC<{
7
+ readonly readOnlyStudio: boolean;
8
+ }>;
@@ -5,11 +5,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
+ const client_id_1 = require("../helpers/client-id");
8
9
  const format_media_duration_1 = require("../helpers/format-media-duration");
9
10
  const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
10
11
  const render_codec_label_1 = require("../helpers/render-codec-label");
11
12
  const use_media_metadata_1 = require("../helpers/use-media-metadata");
13
+ const InlineEditableTitle_1 = require("./InlineEditableTitle");
12
14
  const InspectorInfoHeader_1 = require("./InspectorInfoHeader");
15
+ const use_rename_static_file_1 = require("./NewComposition/use-rename-static-file");
13
16
  const use_static_files_1 = require("./use-static-files");
14
17
  exports.CURRENT_ASSET_HEIGHT = InspectorInfoHeader_1.INSPECTOR_INFO_HEADER_MIN_HEIGHT;
15
18
  const getCurrentAssetMetadataSource = (assetName) => {
@@ -52,11 +55,17 @@ const getCurrentAssetMediaDetailLines = (mediaMetadata) => {
52
55
  return detailLines;
53
56
  };
54
57
  exports.getCurrentAssetMediaDetailLines = getCurrentAssetMediaDetailLines;
55
- const CurrentAsset = () => {
58
+ const CurrentAsset = ({ readOnlyStudio }) => {
56
59
  var _a;
57
60
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
61
+ const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
62
+ .previewServerState.type;
58
63
  const assetName = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'asset' ? canvasContent.asset : null;
59
64
  const staticFiles = (0, use_static_files_1.useStaticFiles)();
65
+ const renameFile = (0, use_rename_static_file_1.useRenameStaticFile)({
66
+ relativePath: assetName !== null && assetName !== void 0 ? assetName : '',
67
+ staticFiles,
68
+ });
60
69
  const sizeInBytes = (0, react_1.useMemo)(() => {
61
70
  var _a;
62
71
  if (!assetName) {
@@ -67,6 +76,10 @@ const CurrentAsset = () => {
67
76
  }, [assetName, staticFiles]);
68
77
  const src = (0, exports.getCurrentAssetMetadataSource)(assetName);
69
78
  const mediaMetadata = (0, use_media_metadata_1.useMediaMetadata)(src);
79
+ const canRename = connectionStatus === 'connected' && !readOnlyStudio;
80
+ const onRename = (0, react_1.useCallback)((newName) => {
81
+ renameFile(newName).catch(() => undefined);
82
+ }, [renameFile]);
70
83
  if (!assetName) {
71
84
  return jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoHeader, {});
72
85
  }
@@ -87,7 +100,7 @@ const CurrentAsset = () => {
87
100
  ? (0, exports.getCurrentAssetMediaDetailLines)(mediaMetadata)
88
101
  : [];
89
102
  return (jsx_runtime_1.jsxs(InspectorInfoHeader_1.InspectorInfoHeader, { children: [
90
- jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoTitle, { children: fileName }), subtitleParts.length > 0 ? (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: subtitleParts.join(' · ') })) : null, mediaMetadata ? (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: (0, format_media_duration_1.formatMediaDuration)(mediaMetadata.duration) })) : null, mediaDetailLines.map((line) => {
103
+ jsx_runtime_1.jsx(InlineEditableTitle_1.InlineEditableTitle, { value: fileName, canRename: canRename, getInitialSelection: use_rename_static_file_1.getStaticFileRenameSelection, onCommit: onRename, title: assetName }), subtitleParts.length > 0 ? (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: subtitleParts.join(' · ') })) : null, mediaMetadata ? (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: (0, format_media_duration_1.formatMediaDuration)(mediaMetadata.duration) })) : null, mediaDetailLines.map((line) => {
91
104
  return jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: line }, line);
92
105
  })] }));
93
106
  };
@@ -7,13 +7,14 @@ const remotion_1 = require("remotion");
7
7
  const is_composition_still_1 = require("../helpers/is-composition-still");
8
8
  const open_in_editor_1 = require("../helpers/open-in-editor");
9
9
  const render_frame_1 = require("../state/render-frame");
10
+ const InlineCompositionName_1 = require("./InlineCompositionName");
10
11
  const InspectorInfoHeader_1 = require("./InspectorInfoHeader");
11
12
  const InspectorSourceLocation_1 = require("./InspectorSourceLocation");
12
13
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
13
14
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
14
15
  exports.CURRENT_COMPOSITION_HEIGHT = InspectorInfoHeader_1.INSPECTOR_INFO_HEADER_MIN_HEIGHT;
15
16
  const CurrentComposition = () => {
16
- var _a;
17
+ var _a, _b;
17
18
  const video = remotion_1.Internals.useVideo();
18
19
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
19
20
  const currentComposition = (0, react_1.useMemo)(() => {
@@ -44,6 +45,6 @@ const CurrentComposition = () => {
44
45
  });
45
46
  }, [validatedLocation]);
46
47
  return (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoHeader, { children: video ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
47
- jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoTitle, { children: video.id }), jsx_runtime_1.jsx(InspectorSourceLocation_1.InspectorSourceLocation, { location: validatedLocation, canOpen: validatedLocation !== null, onOpen: openFileLocation }), jsx_runtime_1.jsxs(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: [video.width, "x", video.height, (0, is_composition_still_1.isCompositionStill)(video) ? null : `, ${video.fps} FPS`] }), (0, is_composition_still_1.isCompositionStill)(video) ? (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: "Still" })) : (jsx_runtime_1.jsxs(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: ["Duration ", (0, render_frame_1.renderFrame)(video.durationInFrames, video.fps)] }))] })) : null }));
48
+ jsx_runtime_1.jsx(InlineCompositionName_1.InlineCompositionName, { compositionId: video.id, stack: (_b = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _b !== void 0 ? _b : null, compositions: compositions }, video.id), jsx_runtime_1.jsx(InspectorSourceLocation_1.InspectorSourceLocation, { location: validatedLocation, canOpen: validatedLocation !== null, onOpen: openFileLocation }), jsx_runtime_1.jsxs(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: [video.width, "x", video.height, (0, is_composition_still_1.isCompositionStill)(video) ? null : `, ${video.fps} FPS`] }), (0, is_composition_still_1.isCompositionStill)(video) ? (jsx_runtime_1.jsx(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: "Still" })) : (jsx_runtime_1.jsxs(InspectorInfoHeader_1.InspectorInfoSubtitle, { children: ["Duration ", (0, render_frame_1.renderFrame)(video.durationInFrames, video.fps)] }))] })) : null }));
48
49
  };
49
50
  exports.CurrentComposition = CurrentComposition;
@@ -69,7 +69,7 @@ const EffectPickerResult = ({ item, selected, onSelected }) => {
69
69
  const labelStyle = (0, react_1.useMemo)(() => {
70
70
  return {
71
71
  ...label,
72
- color: selected || hovered ? 'white' : colors_1.LIGHT_TEXT,
72
+ color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT,
73
73
  };
74
74
  }, [hovered, selected]);
75
75
  const onClick = (0, react_1.useCallback)(() => {
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FilePreview = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
+ const colors_1 = require("../helpers/colors");
6
7
  const JSONViewer_1 = require("./JSONViewer");
7
8
  const layout_1 = require("./layout");
8
9
  const TextViewer_1 = require("./TextViewer");
9
10
  const msgStyle = {
10
11
  fontSize: 13,
11
- color: 'white',
12
+ color: colors_1.WHITE,
12
13
  fontFamily: 'sans-serif',
13
14
  display: 'flex',
14
15
  justifyContent: 'center',