@remotion/studio 4.0.518 → 4.0.520

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 (196) hide show
  1. package/dist/api/visual-control.js +2 -2
  2. package/dist/components/AppLaunchButton.d.ts +16 -0
  3. package/dist/components/AppLaunchButton.js +90 -0
  4. package/dist/components/AssetSelector.js +7 -6
  5. package/dist/components/AssetSelectorItem.d.ts +12 -0
  6. package/dist/components/AssetSelectorItem.js +180 -62
  7. package/dist/components/AudioWaveform.js +6 -1
  8. package/dist/components/Button.js +20 -7
  9. package/dist/components/Canvas.js +117 -92
  10. package/dist/components/CanvasOrLoading.js +7 -7
  11. package/dist/components/CodingAgentButton.d.ts +7 -0
  12. package/dist/components/CodingAgentButton.js +59 -0
  13. package/dist/components/CompositionContextButton.d.ts +1 -0
  14. package/dist/components/CompositionContextButton.js +6 -3
  15. package/dist/components/CompositionSelector.js +21 -20
  16. package/dist/components/CompositionSelectorItem.js +23 -35
  17. package/dist/components/ConfigureLicenseModal.js +4 -48
  18. package/dist/components/CurrentAsset.js +1 -1
  19. package/dist/components/CurrentCompositionSideEffects.js +5 -0
  20. package/dist/components/ElementInstallConfirmation.d.ts +2 -10
  21. package/dist/components/ElementInstallConfirmation.js +339 -32
  22. package/dist/components/FixComputedValueModal.js +5 -131
  23. package/dist/components/FpsCounter.js +1 -1
  24. package/dist/components/FramePersistor.js +1 -1
  25. package/dist/components/InitialCompositionLoader.js +3 -2
  26. package/dist/components/InspectorOpenInEditor.js +48 -33
  27. package/dist/components/InspectorPanel/CompositionInspector.js +35 -3
  28. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +22 -14
  29. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +3 -1
  30. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +1 -1
  31. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +10 -5
  32. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +5 -4
  33. package/dist/components/InspectorPanel/common.js +1 -0
  34. package/dist/components/InspectorPanel/styles.js +1 -0
  35. package/dist/components/InspectorPanel/use-composition-actions.js +5 -8
  36. package/dist/components/InspectorSequenceSection.js +8 -3
  37. package/dist/components/InspectorSourceLocation.js +5 -1
  38. package/dist/components/KnownBugs.d.ts +1 -1
  39. package/dist/components/KnownBugs.js +1 -1
  40. package/dist/components/LicenseExplanation.d.ts +2 -0
  41. package/dist/components/LicenseExplanation.js +63 -0
  42. package/dist/components/MenuToolbar.js +7 -1
  43. package/dist/components/Modals.js +1 -2
  44. package/dist/components/NewComposition/InputDragger.js +29 -2
  45. package/dist/components/NewComposition/NewCompDuration.js +1 -1
  46. package/dist/components/NewComposition/NewComposition.d.ts +23 -0
  47. package/dist/components/NewComposition/NewComposition.js +217 -80
  48. package/dist/components/{UpdateModal/OpenIssueButton.js → OpenIssueButton.js} +1 -1
  49. package/dist/components/PlayPause.js +2 -13
  50. package/dist/components/PreviewToolbar.js +1 -1
  51. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +2 -1
  52. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +50 -28
  53. package/dist/components/QuickSwitcher/QuickSwitcherResult.d.ts +14 -1
  54. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +64 -9
  55. package/dist/components/QuickSwitcher/composition-search.d.ts +16 -0
  56. package/dist/components/QuickSwitcher/composition-search.js +136 -0
  57. package/dist/components/RenderQueue/actions.d.ts +1 -0
  58. package/dist/components/RenderQueue/actions.js +5 -1
  59. package/dist/components/ResetZoomButton.js +17 -2
  60. package/dist/components/SelectedOutlineCanvasRotation.js +27 -1
  61. package/dist/components/SelectedOutlineElement.js +12 -31
  62. package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -2
  63. package/dist/components/SelectedOutlineOverlay.d.ts +3 -1
  64. package/dist/components/SelectedOutlineOverlay.js +21 -26
  65. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  66. package/dist/components/SelectedOutlinePolygon.js +12 -4
  67. package/dist/components/SelectedOutlineRenderer.js +88 -21
  68. package/dist/components/SettingsContext.js +2 -1
  69. package/dist/components/SettingsModal.d.ts +1 -1
  70. package/dist/components/SettingsModal.js +19 -3
  71. package/dist/components/SidebarRenderButton.d.ts +1 -0
  72. package/dist/components/SidebarRenderButton.js +14 -5
  73. package/dist/components/Timeline/SequencePropsObserver.js +29 -14
  74. package/dist/components/Timeline/Timeline.js +2 -1
  75. package/dist/components/Timeline/TimelineAssetField.js +1 -0
  76. package/dist/components/Timeline/TimelineDeleteKeybindings.js +5 -90
  77. package/dist/components/Timeline/TimelineDragHandler.js +18 -8
  78. package/dist/components/Timeline/TimelineInOutDragHandler.js +2 -3
  79. package/dist/components/Timeline/TimelineKeyframeControls.js +3 -1
  80. package/dist/components/Timeline/TimelinePinchZoom.js +14 -4
  81. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +8 -4
  82. package/dist/components/Timeline/TimelineRowChrome.js +4 -2
  83. package/dist/components/Timeline/TimelineSequence.js +52 -45
  84. package/dist/components/Timeline/TimelineSequenceItem.js +44 -32
  85. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -3
  86. package/dist/components/Timeline/TimelineSlider.js +2 -2
  87. package/dist/components/Timeline/TimelineStack/get-stack.d.ts +1 -0
  88. package/dist/components/Timeline/TimelineStack/get-stack.js +35 -3
  89. package/dist/components/Timeline/TimelineWidthProvider.js +15 -8
  90. package/dist/components/Timeline/TimelineZoomControls.js +25 -8
  91. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -2
  92. package/dist/components/Timeline/duplicate-selected-timeline-item.js +23 -25
  93. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -0
  94. package/dist/components/Timeline/get-sequence-context-menu-items.js +34 -1
  95. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -0
  96. package/dist/components/Timeline/sequence-props-subscription-store.js +22 -1
  97. package/dist/components/Timeline/timeline-scroll-logic.d.ts +1 -0
  98. package/dist/components/Timeline/timeline-scroll-logic.js +21 -17
  99. package/dist/components/Timeline/use-delete-timeline-items.d.ts +1 -0
  100. package/dist/components/Timeline/use-delete-timeline-items.js +118 -0
  101. package/dist/components/Timeline/use-sequence-props-subscription.js +7 -0
  102. package/dist/components/Timeline/use-timeline-asset-drop.js +8 -14
  103. package/dist/components/TimelineCombobox.js +1 -0
  104. package/dist/components/UpdateCheck.d.ts +0 -8
  105. package/dist/components/UpdateCheck.js +7 -54
  106. package/dist/components/UpdateStatusContext.d.ts +18 -0
  107. package/dist/components/UpdateStatusContext.js +74 -0
  108. package/dist/components/UpdatesSettings.d.ts +2 -0
  109. package/dist/components/UpdatesSettings.js +251 -0
  110. package/dist/components/WebMcp.js +64 -11
  111. package/dist/components/ZoomPersistor.js +2 -2
  112. package/dist/components/composition-drag-data.d.ts +36 -0
  113. package/dist/components/composition-drag-data.js +232 -0
  114. package/dist/components/drop-handler-data.d.ts +2 -1
  115. package/dist/components/drop-handler-data.js +6 -4
  116. package/dist/components/effect-drag-and-drop.d.ts +2 -5
  117. package/dist/components/get-open-in-menu-items.d.ts +4 -0
  118. package/dist/components/get-open-in-menu-items.js +28 -24
  119. package/dist/components/handle-drop.js +6 -2
  120. package/dist/components/import-assets.d.ts +5 -13
  121. package/dist/components/root-composition-menu-items.d.ts +4 -1
  122. package/dist/components/root-composition-menu-items.js +38 -1
  123. package/dist/components/selected-outline-geometry.d.ts +21 -2
  124. package/dist/components/selected-outline-geometry.js +16 -5
  125. package/dist/components/selected-outline-measurement.d.ts +40 -1
  126. package/dist/components/selected-outline-measurement.js +239 -1
  127. package/dist/components/selected-outline-order.d.ts +12 -0
  128. package/dist/components/selected-outline-order.js +251 -0
  129. package/dist/components/selected-outline-types.d.ts +15 -2
  130. package/dist/components/selected-outline-uv.js +106 -3
  131. package/dist/components/use-configure-default-apps.d.ts +1 -0
  132. package/dist/components/use-configure-default-apps.js +24 -0
  133. package/dist/error-overlay/current-error.d.ts +13 -0
  134. package/dist/error-overlay/current-error.js +21 -0
  135. package/dist/error-overlay/remotion-overlay/CodeFrame.js +5 -6
  136. package/dist/error-overlay/remotion-overlay/CopyStackTrace.js +1 -1
  137. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +47 -18
  138. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +6 -2
  139. package/dist/error-overlay/remotion-overlay/ErrorTitle.js +5 -4
  140. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +48 -76
  141. package/dist/error-overlay/remotion-overlay/SearchGitHubIssues.js +1 -1
  142. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +2 -2
  143. package/dist/error-overlay/remotion-overlay/StackFrame.js +13 -8
  144. package/dist/error-overlay/remotion-overlay/Symbolicating.js +1 -1
  145. package/dist/esm/chunk-6jf1natv.js +25 -0
  146. package/dist/esm/{chunk-4bxz1d3g.js → chunk-je0h1bgt.js} +1 -28
  147. package/dist/esm/chunk-m0jqdbkr.js +14571 -0
  148. package/dist/esm/{chunk-7prjt5n5.js → chunk-np6q13k5.js} +18637 -12189
  149. package/dist/esm/index.mjs +4 -3
  150. package/dist/esm/internals.mjs +35826 -14822
  151. package/dist/esm/previewEntry.mjs +40028 -18935
  152. package/dist/esm/renderEntry.mjs +6 -3
  153. package/dist/helpers/can-show-updates.d.ts +5 -0
  154. package/dist/helpers/can-show-updates.js +7 -0
  155. package/dist/helpers/colors.d.ts +0 -3
  156. package/dist/helpers/colors.js +2 -5
  157. package/dist/helpers/create-folder-tree.d.ts +5 -0
  158. package/dist/helpers/create-folder-tree.js +26 -6
  159. package/dist/helpers/document-title.d.ts +2 -0
  160. package/dist/helpers/document-title.js +14 -3
  161. package/dist/helpers/get-asset-metadata.js +1 -1
  162. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +82 -0
  163. package/dist/helpers/get-box-quads-polyfill-internals.js +2403 -0
  164. package/dist/helpers/get-box-quads-ponyfill.d.ts +10 -0
  165. package/dist/helpers/get-box-quads-ponyfill.js +23 -0
  166. package/dist/helpers/get-git-menu-item.d.ts +5 -0
  167. package/dist/helpers/get-git-menu-item.js +15 -1
  168. package/dist/helpers/get-timeline-max-zoom.d.ts +34 -28
  169. package/dist/helpers/get-timeline-max-zoom.js +46 -29
  170. package/dist/helpers/hoverable.js +10 -5
  171. package/dist/helpers/install-fiber-sequence-order-observer.d.ts +37 -0
  172. package/dist/helpers/install-fiber-sequence-order-observer.js +109 -0
  173. package/dist/helpers/open-in-editor.js +53 -2
  174. package/dist/helpers/preview-server-events.js +3 -0
  175. package/dist/helpers/timeline-layout.d.ts +0 -1
  176. package/dist/helpers/timeline-layout.js +1 -5
  177. package/dist/helpers/url-state.d.ts +1 -0
  178. package/dist/helpers/url-state.js +12 -5
  179. package/dist/helpers/use-runtime-values.d.ts +1 -1
  180. package/dist/helpers/use-runtime-values.js +5 -4
  181. package/dist/helpers/use-sync-external-store.d.ts +3 -0
  182. package/dist/helpers/use-sync-external-store.js +5 -0
  183. package/dist/previewEntry.js +2 -0
  184. package/dist/renderEntry.js +2 -0
  185. package/dist/state/folders.d.ts +3 -0
  186. package/dist/state/folders.js +40 -1
  187. package/dist/state/modals.d.ts +19 -8
  188. package/dist/state/timeline-sequence-hover.js +3 -2
  189. package/dist/state/timeline-zoom.d.ts +0 -1
  190. package/dist/state/timeline-zoom.js +13 -6
  191. package/package.json +18 -15
  192. package/dist/components/UpdateModal/UpdateModal.d.ts +0 -6
  193. package/dist/components/UpdateModal/UpdateModal.js +0 -104
  194. package/dist/helpers/sort-by-nonce-history.d.ts +0 -1
  195. package/dist/helpers/sort-by-nonce-history.js +0 -6
  196. /package/dist/components/{UpdateModal/OpenIssueButton.d.ts → OpenIssueButton.d.ts} +0 -0
@@ -5,6 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const colors_1 = require("../../helpers/colors");
8
+ const create_folder_tree_1 = require("../../helpers/create-folder-tree");
8
9
  const get_preview_file_type_1 = require("../../helpers/get-preview-file-type");
9
10
  const is_composition_still_1 = require("../../helpers/is-composition-still");
10
11
  const url_state_1 = require("../../helpers/url-state");
@@ -19,6 +20,7 @@ const use_select_asset_1 = require("../use-select-asset");
19
20
  const use_static_files_1 = require("../use-static-files");
20
21
  const algolia_search_1 = require("./algolia-search");
21
22
  const asset_search_1 = require("./asset-search");
23
+ const composition_search_1 = require("./composition-search");
22
24
  const fuzzy_search_1 = require("./fuzzy-search");
23
25
  const NoResults_1 = require("./NoResults");
24
26
  const QuickSwitcherResult_1 = require("./QuickSwitcherResult");
@@ -27,6 +29,10 @@ const input = {
27
29
  width: '100%',
28
30
  borderRadius: 4,
29
31
  };
32
+ const touchscreenInput = {
33
+ ...input,
34
+ fontSize: 16,
35
+ };
30
36
  const modeSelector = {
31
37
  paddingLeft: 16,
32
38
  paddingRight: 16,
@@ -42,6 +48,7 @@ const modeItem = {
42
48
  padding: 0,
43
49
  fontSize: 13,
44
50
  cursor: 'pointer',
51
+ userSelect: 'none',
45
52
  };
46
53
  const modeInactive = {
47
54
  ...modeItem,
@@ -103,7 +110,9 @@ const mapModeToQuery = (mode) => {
103
110
  throw new Error('no mode' + mode);
104
111
  };
105
112
  const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio, assetSelection, compositionSelection, }) => {
106
- const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
113
+ var _a;
114
+ var _b;
115
+ const { compositions, folders } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
107
116
  const staticFiles = (0, use_static_files_1.useStaticFiles)();
108
117
  const [state, setState] = (0, react_1.useState)(() => {
109
118
  return {
@@ -126,6 +135,7 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
126
135
  });
127
136
  }, [assetSelection, compositionSelection, initialMode, invocationTimestamp]);
128
137
  const inputRef = (0, react_1.useRef)(null);
138
+ const isTouchscreen = navigator.maxTouchPoints > 0;
129
139
  const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
130
140
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
131
141
  const closeMenu = (0, react_1.useCallback)(() => undefined, []);
@@ -195,37 +205,45 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
195
205
  ...assetResults,
196
206
  ];
197
207
  }
198
- return (0, fuzzy_search_1.fuzzySearch)(actualQuery, compositions
199
- .filter((c) => c.id !== (compositionSelection === null || compositionSelection === void 0 ? void 0 : compositionSelection.excludeCompositionId))
200
- .map((c) => {
208
+ const tree = (0, create_folder_tree_1.createFolderTree)(compositions.filter((composition) => composition.id !== (compositionSelection === null || compositionSelection === void 0 ? void 0 : compositionSelection.excludeCompositionId)), folders, {});
209
+ return (0, composition_search_1.searchCompositionTree)({ items: tree, query: actualQuery }).map((result) => {
210
+ if (result.type === 'folder') {
211
+ return result;
212
+ }
213
+ const { composition } = result;
201
214
  return {
202
- id: 'composition-' + c.id,
203
- title: c.id,
215
+ id: 'composition-' + composition.id,
216
+ title: composition.id,
204
217
  type: 'composition',
218
+ composition,
219
+ level: result.level,
205
220
  onSelected: () => {
206
221
  var _a;
207
222
  if (compositionSelection !== null) {
208
- compositionSelection.onSelected(c);
223
+ compositionSelection.onSelected(composition);
209
224
  setSelectedModal(null);
210
225
  return;
211
226
  }
212
- selectComposition(c, true);
227
+ selectComposition(composition, true);
213
228
  setSelectedModal(null);
214
- const selector = `.__remotion-composition[data-compname="${c.id}"]`;
215
- (_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.expandComposition(c.id);
229
+ const selector = `.__remotion-composition[data-compname="${composition.id}"]`;
230
+ (_a = remotion_1.Internals.compositionSelectorRef.current) === null || _a === void 0 ? void 0 : _a.expandComposition(composition.id);
216
231
  waitForElm(selector).then(() => {
217
232
  var _a;
218
233
  (_a = document
219
234
  .querySelector(selector)) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'center' });
220
235
  });
221
236
  },
222
- compositionType: (0, is_composition_still_1.isCompositionStill)(c) ? 'still' : 'composition',
237
+ compositionType: (0, is_composition_still_1.isCompositionStill)(composition)
238
+ ? 'still'
239
+ : 'composition',
223
240
  };
224
- }));
241
+ });
225
242
  }, [
226
243
  mode,
227
244
  actualQuery,
228
245
  compositions,
246
+ folders,
229
247
  menuActions,
230
248
  docResults,
231
249
  assetSearch,
@@ -313,40 +331,44 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
313
331
  const onTextChange = (0, react_1.useCallback)((e) => {
314
332
  setState({ query: e.target.value, selectedIndex: 0 });
315
333
  }, []);
316
- const selectedIndexRounded = (0, shared_1.loopIndex)(state.selectedIndex, resultsArray.length);
317
- const onActionsSelected = (0, react_1.useCallback)(() => {
334
+ const selectableResults = resultsArray.filter(QuickSwitcherResult_1.isQuickSwitcherResultSelectable);
335
+ const selectedIndexRounded = (0, shared_1.loopIndex)(state.selectedIndex, selectableResults.length);
336
+ const selectedResultId = (_b = (_a = selectableResults[selectedIndexRounded]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
337
+ const focusInput = (0, react_1.useCallback)(() => {
318
338
  var _a;
339
+ if (!isTouchscreen) {
340
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
341
+ }
342
+ }, [isTouchscreen]);
343
+ const onActionsSelected = (0, react_1.useCallback)(() => {
319
344
  setState((s) => ({
320
345
  query: `> ${stripQuery(s.query)}`,
321
346
  selectedIndex: 0,
322
347
  }));
323
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
324
- }, []);
348
+ focusInput();
349
+ }, [focusInput]);
325
350
  const onCompositionsSelected = (0, react_1.useCallback)(() => {
326
- var _a;
327
351
  setState((s) => ({
328
352
  query: stripQuery(s.query),
329
353
  selectedIndex: 0,
330
354
  }));
331
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
332
- }, []);
355
+ focusInput();
356
+ }, [focusInput]);
333
357
  const onAssetsSelected = (0, react_1.useCallback)(() => {
334
- var _a;
335
358
  setState((s) => ({
336
359
  query: `$ ${stripQuery(s.query)}`,
337
360
  selectedIndex: 0,
338
361
  }));
339
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
340
- }, []);
362
+ focusInput();
363
+ }, [focusInput]);
341
364
  const onDocSearchSelected = (0, react_1.useCallback)(() => {
342
- var _a;
343
365
  setState((s) => ({
344
366
  query: `? ${stripQuery(s.query)}`,
345
367
  selectedIndex: 0,
346
368
  }));
347
369
  setDocResults({ type: 'initial' });
348
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
349
- }, []);
370
+ focusInput();
371
+ }, [focusInput]);
350
372
  const showSearchLoadingState = mode === 'docs' && docResults.type === 'loading';
351
373
  const showEmptyDocSearch = mode === 'docs' && actualQuery.trim() === '';
352
374
  const placeholder = mode === 'assets'
@@ -360,9 +382,9 @@ const QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio
360
382
  jsx_runtime_1.jsx("button", { onClick: onCompositionsSelected, style: mode === 'compositions' ? modeActive : modeInactive, type: "button", children: "Compositions" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("button", { onClick: onAssetsSelected, style: mode === 'assets' ? modeActive : modeInactive, type: "button", children: "Assets" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("button", { onClick: onActionsSelected, style: mode === 'commands' ? modeActive : modeInactive, type: "button", children: "Actions" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("button", { onClick: onDocSearchSelected, style: mode === 'docs' ? modeActive : modeInactive, type: "button", children: "Documentation" })
361
383
  ] })), jsx_runtime_1.jsx("div", { style: assetSelection === null && compositionSelection === null
362
384
  ? content
363
- : contentWithoutModeSelector, children: jsx_runtime_1.jsx(RemInput_1.RemotionInput, { ref: inputRef, type: "text", style: input, autoFocus: true, status: "ok", value: state.query, onChange: onTextChange, placeholder: placeholder, rightAlign: false }) }), jsx_runtime_1.jsx("div", { style: results, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: showEmptyDocSearch ||
364
- showSearchLoadingState ? null : resultsArray.length === 0 ? (jsx_runtime_1.jsx(NoResults_1.QuickSwitcherNoResults, { mode: mode, query: actualQuery })) : (resultsArray.map((result, i) => {
365
- return (jsx_runtime_1.jsx(QuickSwitcherResult_1.QuickSwitcherResult, { selected: selectedIndexRounded === i, result: result }, result.id));
385
+ : contentWithoutModeSelector, children: jsx_runtime_1.jsx(RemInput_1.RemotionInput, { ref: inputRef, type: "text", style: isTouchscreen ? touchscreenInput : input, autoFocus: !isTouchscreen, status: "ok", value: state.query, onChange: onTextChange, placeholder: placeholder, rightAlign: false }) }), jsx_runtime_1.jsx("div", { style: results, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: showEmptyDocSearch ||
386
+ showSearchLoadingState ? null : resultsArray.length === 0 ? (jsx_runtime_1.jsx(NoResults_1.QuickSwitcherNoResults, { mode: mode, query: actualQuery })) : (resultsArray.map((result) => {
387
+ return (jsx_runtime_1.jsx(QuickSwitcherResult_1.QuickSwitcherResult, { selected: selectedResultId === result.id, result: result }, result.id));
366
388
  })) })
367
389
  ] }));
368
390
  };
@@ -1,11 +1,14 @@
1
1
  import React from 'react';
2
+ import type { _InternalTypes } from 'remotion';
2
3
  import type { AssetFileType } from '../../helpers/get-preview-file-type';
3
4
  type QuickSwitcherResultDetail = {
4
5
  type: 'asset';
5
6
  fileType: AssetFileType;
6
7
  } | {
7
8
  type: 'composition';
9
+ composition: _InternalTypes['AnyComposition'];
8
10
  compositionType: 'composition' | 'still';
11
+ level: number;
9
12
  } | {
10
13
  type: 'menu-item';
11
14
  } | {
@@ -15,7 +18,17 @@ type QuickSwitcherResultDetail = {
15
18
  titleLine: string;
16
19
  subtitleLine: string;
17
20
  };
18
- export type TQuickSwitcherResult = {
21
+ export type TQuickSwitcherResult = ({
22
+ title: string;
23
+ id: string;
24
+ onSelected: () => void;
25
+ } & QuickSwitcherResultDetail) | {
26
+ title: string;
27
+ id: string;
28
+ type: 'folder';
29
+ level: number;
30
+ };
31
+ export declare const isQuickSwitcherResultSelectable: (result: TQuickSwitcherResult) => result is {
19
32
  title: string;
20
33
  id: string;
21
34
  onSelected: () => void;
@@ -1,16 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QuickSwitcherResult = void 0;
3
+ exports.QuickSwitcherResult = exports.isQuickSwitcherResultSelectable = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const client_id_1 = require("../../helpers/client-id");
6
7
  const colors_1 = require("../../helpers/colors");
8
+ const noop_1 = require("../../helpers/noop");
7
9
  const use_keybinding_1 = require("../../helpers/use-keybinding");
10
+ const folder_1 = require("../../icons/folder");
8
11
  const still_1 = require("../../icons/still");
9
12
  const upload_1 = require("../../icons/upload");
10
13
  const video_1 = require("../../icons/video");
14
+ const modals_1 = require("../../state/modals");
11
15
  const AssetFileIcon_1 = require("../AssetFileIcon");
16
+ const composition_menu_items_1 = require("../composition-menu-items");
17
+ const ContextMenu_1 = require("../ContextMenu");
12
18
  const layout_1 = require("../layout");
19
+ const use_resolved_stack_1 = require("../Timeline/use-resolved-stack");
20
+ const use_default_editor_info_1 = require("../use-default-editor-info");
13
21
  const shared_1 = require("./shared");
22
+ const isQuickSwitcherResultSelectable = (result) => {
23
+ return result.type !== 'folder';
24
+ };
25
+ exports.isQuickSwitcherResultSelectable = isQuickSwitcherResultSelectable;
14
26
  const container = {
15
27
  paddingLeft: 16,
16
28
  paddingRight: 16,
@@ -48,10 +60,44 @@ const labelContainer = {
48
60
  paddingBottom: 5,
49
61
  };
50
62
  const QuickSwitcherResult = ({ result, selected }) => {
63
+ var _a;
51
64
  const [hovered, setIsHovered] = (0, react_1.useState)(false);
52
65
  const ref = (0, react_1.useRef)(null);
53
66
  const keybindings = (0, use_keybinding_1.useKeybinding)();
67
+ const onSelected = result.type === 'folder' ? null : result.onSelected;
68
+ const composition = result.type === 'composition' ? result.composition : null;
69
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
70
+ const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
71
+ .previewServerState.type;
72
+ const { defaultEditorId, defaultEditorName } = (0, use_default_editor_info_1.useEditorOpening)(connectionStatus === 'connected');
73
+ const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = composition === null || composition === void 0 ? void 0 : composition.stack) !== null && _a !== void 0 ? _a : null);
74
+ const getContextMenuItems = (0, react_1.useCallback)(() => {
75
+ if (composition === null) {
76
+ return [];
77
+ }
78
+ return (0, composition_menu_items_1.getCompositionContextMenuItems)({
79
+ closeMenu: noop_1.noop,
80
+ composition,
81
+ connectionStatus,
82
+ editorId: defaultEditorId,
83
+ editorName: defaultEditorName,
84
+ includeCompositionManagementItems: true,
85
+ resolvedLocation,
86
+ setSelectedModal,
87
+ readOnlyStudio: window.remotion_isReadOnlyStudio,
88
+ });
89
+ }, [
90
+ composition,
91
+ connectionStatus,
92
+ defaultEditorId,
93
+ defaultEditorName,
94
+ resolvedLocation,
95
+ setSelectedModal,
96
+ ]);
54
97
  (0, react_1.useEffect)(() => {
98
+ if (result.type === 'folder') {
99
+ return;
100
+ }
55
101
  const { current } = ref;
56
102
  if (!current) {
57
103
  return;
@@ -64,14 +110,14 @@ const QuickSwitcherResult = ({ result, selected }) => {
64
110
  current.removeEventListener('mouseenter', onMouseEnter);
65
111
  current.removeEventListener('mouseleave', onMouseLeave);
66
112
  };
67
- }, []);
113
+ }, [result.type]);
68
114
  (0, react_1.useEffect)(() => {
69
- if (!selected) {
115
+ if (!selected || onSelected === null) {
70
116
  return;
71
117
  }
72
118
  const binding = keybindings.registerKeybinding({
73
119
  key: 'Enter',
74
- callback: result.onSelected,
120
+ callback: onSelected,
75
121
  commandCtrlKey: false,
76
122
  event: 'keydown',
77
123
  preventDefault: true,
@@ -82,18 +128,23 @@ const QuickSwitcherResult = ({ result, selected }) => {
82
128
  return () => {
83
129
  binding.unregister();
84
130
  };
85
- }, [keybindings, result.onSelected, selected]);
131
+ }, [keybindings, onSelected, selected]);
86
132
  (0, shared_1.useScrollIntoViewOnSelected)(ref, selected);
87
133
  const style = (0, react_1.useMemo)(() => {
88
134
  return {
89
135
  ...container,
90
- backgroundColor: hovered || selected ? colors_1.WHITE_ALPHA_06 : colors_1.TRANSPARENT,
136
+ paddingLeft: result.type === 'folder' || result.type === 'composition'
137
+ ? 16 + result.level * 8
138
+ : container.paddingLeft,
139
+ backgroundColor: result.type !== 'folder' && (hovered || selected)
140
+ ? colors_1.WHITE_ALPHA_06
141
+ : colors_1.TRANSPARENT,
91
142
  };
92
- }, [hovered, selected]);
143
+ }, [hovered, result, selected]);
93
144
  const labelStyle = (0, react_1.useMemo)(() => {
94
145
  return {
95
146
  ...(result.type === 'search-result' ? searchLabel : label),
96
- color: result.type === 'search-result'
147
+ color: result.type === 'search-result' || result.type === 'folder'
97
148
  ? colors_1.LIGHT_TEXT
98
149
  : selected || hovered
99
150
  ? colors_1.WHITE
@@ -101,7 +152,7 @@ const QuickSwitcherResult = ({ result, selected }) => {
101
152
  fontSize: shared_1.QUICK_SWITCHER_RESULT_LABEL_FONT_SIZE,
102
153
  };
103
154
  }, [hovered, result.type, selected]);
104
- return (jsx_runtime_1.jsxs("div", { ref: ref, style: style, onClick: result.onSelected, children: [result.type === 'composition' ? (result.compositionType === 'still' ? (jsx_runtime_1.jsx(still_1.StillIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })) : (jsx_runtime_1.jsx(video_1.FilmIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle }))) : result.type === 'asset' ? (jsx_runtime_1.jsx(AssetFileIcon_1.AssetFileIcon, { fileType: result.fileType, color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })) : result.type === 'select-file' ? (jsx_runtime_1.jsx(upload_1.UploadIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: selectFileIconStyle })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: labelContainer, children: result.type === 'search-result' ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
155
+ const row = (jsx_runtime_1.jsxs("div", { ref: ref, style: style, onClick: onSelected !== null && onSelected !== void 0 ? onSelected : undefined, children: [result.type === 'composition' ? (result.compositionType === 'still' ? (jsx_runtime_1.jsx(still_1.StillIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })) : (jsx_runtime_1.jsx(video_1.FilmIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle }))) : result.type === 'folder' ? (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { color: colors_1.LIGHT_TEXT, style: iconStyle })) : result.type === 'asset' ? (jsx_runtime_1.jsx(AssetFileIcon_1.AssetFileIcon, { fileType: result.fileType, color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })) : result.type === 'select-file' ? (jsx_runtime_1.jsx(upload_1.UploadIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: selectFileIconStyle })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: labelContainer, children: result.type === 'search-result' ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
105
156
  jsx_runtime_1.jsx("div", {
106
157
  // eslint-disable-next-line react/no-danger
107
158
  dangerouslySetInnerHTML: {
@@ -113,5 +164,9 @@ const QuickSwitcherResult = ({ result, selected }) => {
113
164
  }, style: labelStyle })
114
165
  ] })) : (jsx_runtime_1.jsx("div", { style: labelStyle, children: result.title })) })
115
166
  ] }, result.id));
167
+ if (composition === null) {
168
+ return row;
169
+ }
170
+ return jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: row });
116
171
  };
117
172
  exports.QuickSwitcherResult = QuickSwitcherResult;
@@ -0,0 +1,16 @@
1
+ import type { _InternalTypes } from 'remotion';
2
+ import type { CompositionSelectorItemType } from '../CompositionSelectorItem';
3
+ export type CompositionSearchResult = {
4
+ readonly type: 'folder';
5
+ readonly id: string;
6
+ readonly title: string;
7
+ readonly level: number;
8
+ } | {
9
+ readonly type: 'composition';
10
+ readonly composition: _InternalTypes['AnyComposition'];
11
+ readonly level: number;
12
+ };
13
+ export declare const searchCompositionTree: ({ items, query, }: {
14
+ readonly items: CompositionSelectorItemType[];
15
+ readonly query: string;
16
+ }) => CompositionSearchResult[];
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.searchCompositionTree = void 0;
4
+ const normalizeSearchText = (text) => {
5
+ return text
6
+ .trim()
7
+ .toLowerCase()
8
+ .replace(/[\s/-]/g, '');
9
+ };
10
+ const getMatchScore = (query, candidate) => {
11
+ const normalizedCandidate = normalizeSearchText(candidate);
12
+ if (normalizedCandidate === query) {
13
+ return 400000 - normalizedCandidate.length;
14
+ }
15
+ if (normalizedCandidate.startsWith(query)) {
16
+ return 300000 - (normalizedCandidate.length - query.length);
17
+ }
18
+ const substringIndex = normalizedCandidate.indexOf(query);
19
+ if (substringIndex !== -1) {
20
+ return (200000 -
21
+ substringIndex * 100 -
22
+ (normalizedCandidate.length - query.length));
23
+ }
24
+ let previousIndex = -1;
25
+ let firstIndex = -1;
26
+ let gapCount = 0;
27
+ for (const character of query) {
28
+ const nextIndex = normalizedCandidate.indexOf(character, previousIndex + 1);
29
+ if (nextIndex === -1) {
30
+ return null;
31
+ }
32
+ if (firstIndex === -1) {
33
+ firstIndex = nextIndex;
34
+ }
35
+ else {
36
+ gapCount += nextIndex - previousIndex - 1;
37
+ }
38
+ previousIndex = nextIndex;
39
+ }
40
+ return (100000 -
41
+ gapCount * 100 -
42
+ firstIndex * 10 -
43
+ (normalizedCandidate.length - query.length));
44
+ };
45
+ const searchCompositionTree = ({ items, query, }) => {
46
+ const normalizedQuery = normalizeSearchText(query);
47
+ const filterAndRank = (treeItems, level, inheritedFolderScore) => {
48
+ const rankedItems = treeItems
49
+ .map((item, originalIndex) => {
50
+ if (item.type === 'composition') {
51
+ const compositionPath = [
52
+ item.composition.parentFolderName,
53
+ item.composition.folderName,
54
+ item.composition.id,
55
+ ]
56
+ .filter(Boolean)
57
+ .join('/');
58
+ const idScore = normalizedQuery === ''
59
+ ? 0
60
+ : getMatchScore(normalizedQuery, item.composition.id);
61
+ const compositionPathScore = normalizedQuery === ''
62
+ ? 0
63
+ : getMatchScore(normalizedQuery, compositionPath);
64
+ const directScore = Math.max(idScore !== null && idScore !== void 0 ? idScore : -1, compositionPathScore !== null && compositionPathScore !== void 0 ? compositionPathScore : -1);
65
+ const score = Math.max(directScore, inheritedFolderScore !== null && inheritedFolderScore !== void 0 ? inheritedFolderScore : -1);
66
+ if (score === -1) {
67
+ return null;
68
+ }
69
+ return {
70
+ result: {
71
+ type: 'composition',
72
+ composition: item.composition,
73
+ level,
74
+ score,
75
+ },
76
+ originalIndex,
77
+ };
78
+ }
79
+ const fullPath = [item.parentName, item.folderName]
80
+ .filter(Boolean)
81
+ .join('/');
82
+ const nameScore = normalizedQuery === ''
83
+ ? 0
84
+ : getMatchScore(normalizedQuery, item.folderName);
85
+ const pathScore = normalizedQuery === '' ? 0 : getMatchScore(normalizedQuery, fullPath);
86
+ const directFolderScore = Math.max(nameScore !== null && nameScore !== void 0 ? nameScore : -1, pathScore !== null && pathScore !== void 0 ? pathScore : -1);
87
+ const folderScore = Math.max(directFolderScore === -1 ? -1 : directFolderScore - 1, inheritedFolderScore !== null && inheritedFolderScore !== void 0 ? inheritedFolderScore : -1);
88
+ const children = filterAndRank(item.items, level + 1, folderScore === -1 ? null : folderScore);
89
+ if (children.length === 0) {
90
+ return null;
91
+ }
92
+ return {
93
+ result: {
94
+ type: 'folder',
95
+ id: `folder-${fullPath}`,
96
+ title: item.folderName,
97
+ level,
98
+ score: Math.max(folderScore, ...children.map((child) => child.score)),
99
+ children,
100
+ },
101
+ originalIndex,
102
+ };
103
+ })
104
+ .filter((item) => item !== null);
105
+ if (normalizedQuery !== '') {
106
+ rankedItems.sort((a, b) => {
107
+ return (b.result.score - a.result.score || a.originalIndex - b.originalIndex);
108
+ });
109
+ }
110
+ return rankedItems.map((item) => item.result);
111
+ };
112
+ const flatten = (rankedItems) => {
113
+ return rankedItems.flatMap((item) => {
114
+ if (item.type === 'composition') {
115
+ return [
116
+ {
117
+ type: 'composition',
118
+ composition: item.composition,
119
+ level: item.level,
120
+ },
121
+ ];
122
+ }
123
+ return [
124
+ {
125
+ type: 'folder',
126
+ id: item.id,
127
+ title: item.title,
128
+ level: item.level,
129
+ },
130
+ ...flatten(item.children),
131
+ ];
132
+ });
133
+ };
134
+ return flatten(filterAndRank(items, 0, null));
135
+ };
136
+ exports.searchCompositionTree = searchCompositionTree;
@@ -109,6 +109,7 @@ export declare const applyCodemod: ({ codemod, dryRun, symbolicatedStack, signal
109
109
  export declare const removeRenderJob: (job: RenderJob) => Promise<undefined>;
110
110
  export declare const cancelRenderJob: (job: RenderJob) => Promise<import("@remotion/studio-shared").CancelRenderResponse>;
111
111
  export declare const updateAvailable: (signal: AbortSignal) => Promise<import("@remotion/studio-shared").UpdateAvailableResponse>;
112
+ export declare const getReleaseNotes: (currentVersion: string, latestVersion: string, signal: AbortSignal) => Promise<import("@remotion/studio-shared").GetReleaseNotesResponse>;
112
113
  export declare const getProjectInfo: (signal: AbortSignal) => Promise<import("@remotion/studio-shared").ProjectInfoResponse>;
113
114
  export declare const callUpdateDefaultPropsApi: (compositionId: string, defaultProps: Record<string, unknown>, enumPaths: EnumPath[]) => Promise<import("@remotion/studio-shared").UpdateDefaultPropsResponse>;
114
115
  export declare const applyVisualControlChange: ({ fileName, changes, }: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.applyVisualControlChange = exports.callUpdateDefaultPropsApi = exports.getProjectInfo = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.applyCodemod = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addSequenceRenderJob = exports.addStillRenderJob = void 0;
3
+ exports.applyVisualControlChange = exports.callUpdateDefaultPropsApi = exports.getProjectInfo = exports.getReleaseNotes = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.applyCodemod = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addSequenceRenderJob = exports.addStillRenderJob = void 0;
4
4
  const no_react_1 = require("remotion/no-react");
5
5
  const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
6
6
  const call_api_1 = require("../call-api");
@@ -166,6 +166,10 @@ const updateAvailable = (signal) => {
166
166
  return (0, call_api_1.callApi)('/api/update-available', {}, signal);
167
167
  };
168
168
  exports.updateAvailable = updateAvailable;
169
+ const getReleaseNotes = (currentVersion, latestVersion, signal) => {
170
+ return (0, call_api_1.callApi)('/api/release-notes', { currentVersion, latestVersion }, signal);
171
+ };
172
+ exports.getReleaseNotes = getReleaseNotes;
169
173
  const getProjectInfo = (signal) => {
170
174
  return (0, call_api_1.callApi)('/api/project-info', {}, signal);
171
175
  };
@@ -3,11 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ResetZoomButton = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const Button_1 = require("./Button");
6
+ const colors_1 = require("../helpers/colors");
7
+ const button = {
8
+ appearance: 'none',
9
+ backgroundColor: colors_1.INPUT_BACKGROUND,
10
+ border: `1px solid ${colors_1.BLACK_ALPHA_60}`,
11
+ borderRadius: 4,
12
+ color: colors_1.WHITE,
13
+ flexDirection: 'row',
14
+ fontFamily: 'inherit',
15
+ fontSize: 14,
16
+ };
17
+ const buttonContainer = {
18
+ cursor: 'pointer',
19
+ fontSize: 14,
20
+ padding: 10,
21
+ };
7
22
  const ResetZoomButton = ({ onClick }) => {
8
23
  const onPointerDown = (0, react_1.useCallback)((event) => {
9
24
  event.stopPropagation();
10
25
  }, []);
11
- return (jsx_runtime_1.jsx(Button_1.Button, { onClick: onClick, onPointerDown: onPointerDown, children: "Reset zoom" }));
26
+ return (jsx_runtime_1.jsx("button", { style: button, type: "button", onClick: onClick, onPointerDown: onPointerDown, children: jsx_runtime_1.jsx("div", { className: "css-reset", style: buttonContainer, children: "Reset zoom" }) }));
12
27
  };
13
28
  exports.ResetZoomButton = ResetZoomButton;
@@ -38,6 +38,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
40
40
  const colors_1 = require("../helpers/colors");
41
+ const is_mac_1 = require("../helpers/is-mac");
41
42
  const pointer_session_1 = require("../helpers/pointer-session");
42
43
  const editor_snapping_1 = require("../state/editor-snapping");
43
44
  const canvas_rotation_cursor_1 = require("./canvas-rotation-cursor");
@@ -57,9 +58,34 @@ const SelectedOutlineCanvasRotation = ({ getLatestTargetByKey, layoutTarget, onD
57
58
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
58
59
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
59
60
  const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
61
+ const [commandKeyPressed, setCommandKeyPressed] = react_1.default.useState(false);
60
62
  const cursor = transform3DMode
61
63
  ? canvas_rotation_cursor_1.canvasRotationCursor
62
64
  : canvas2DRotationCursor;
65
+ react_1.default.useEffect(() => {
66
+ const commandKey = is_mac_1.isMac ? 'Meta' : 'Control';
67
+ const onKeyDown = (event) => {
68
+ if (event.key === commandKey) {
69
+ setCommandKeyPressed(true);
70
+ }
71
+ };
72
+ const onKeyUp = (event) => {
73
+ if (event.key === commandKey) {
74
+ setCommandKeyPressed(false);
75
+ }
76
+ };
77
+ const onBlur = () => {
78
+ setCommandKeyPressed(false);
79
+ };
80
+ window.addEventListener('keydown', onKeyDown);
81
+ window.addEventListener('keyup', onKeyUp);
82
+ window.addEventListener('blur', onBlur);
83
+ return () => {
84
+ window.removeEventListener('keydown', onKeyDown);
85
+ window.removeEventListener('keyup', onKeyUp);
86
+ window.removeEventListener('blur', onBlur);
87
+ };
88
+ }, []);
63
89
  const onPointerDown = react_1.default.useCallback((event) => {
64
90
  var _a, _b;
65
91
  if (event.button !== 0) {
@@ -241,6 +267,6 @@ const SelectedOutlineCanvasRotation = ({ getLatestTargetByKey, layoutTarget, onD
241
267
  setDragOverrides,
242
268
  setPropStatuses,
243
269
  ]);
244
- return (jsx_runtime_1.jsx("polygon", { points: outline.points.map((point) => `${point.x},${point.y}`).join(' '), fill: colors_1.TRANSPARENT, pointerEvents: "all", cursor: cursor, onPointerDown: onPointerDown, "data-remotion-studio-canvas-rotation": true }));
270
+ return (jsx_runtime_1.jsx("polygon", { points: outline.points.map((point) => `${point.x},${point.y}`).join(' '), fill: colors_1.TRANSPARENT, pointerEvents: commandKeyPressed ? 'none' : 'all', cursor: commandKeyPressed ? 'default' : cursor, onPointerDown: onPointerDown, "data-remotion-studio-canvas-rotation": true }));
245
271
  };
246
272
  exports.SelectedOutlineCanvasRotation = SelectedOutlineCanvasRotation;