@remotion/studio 4.0.498 → 4.0.499

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 (48) hide show
  1. package/dist/components/AssetSelectorItem.js +31 -3
  2. package/dist/components/Canvas.js +162 -7
  3. package/dist/components/CompositionSelector.js +13 -10
  4. package/dist/components/CompositionSelectorItem.js +21 -13
  5. package/dist/components/EditorContent.js +1 -1
  6. package/dist/components/EditorRuler/Ruler.js +5 -3
  7. package/dist/components/ForceSpecificCursor.js +13 -1
  8. package/dist/components/NewComposition/InputDragger.d.ts +27 -0
  9. package/dist/components/NewComposition/InputDragger.js +151 -23
  10. package/dist/components/Splitter/SplitterContainer.d.ts +2 -0
  11. package/dist/components/Splitter/SplitterContainer.js +5 -1
  12. package/dist/components/Splitter/SplitterContext.d.ts +2 -0
  13. package/dist/components/Splitter/SplitterContext.js +2 -0
  14. package/dist/components/Splitter/SplitterElement.js +6 -1
  15. package/dist/components/Splitter/SplitterHandle.js +27 -2
  16. package/dist/components/Timeline/Timeline.js +1 -1
  17. package/dist/components/Timeline/TimelineInOutDragHandler.js +25 -1
  18. package/dist/components/Timeline/TimelineLayerEye.js +4 -1
  19. package/dist/components/Timeline/TimelineSequence.js +6 -1
  20. package/dist/components/Timeline/TimelineSequenceName.js +1 -0
  21. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +5 -1
  22. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +29 -11
  23. package/dist/components/Timeline/use-timeline-keyframe-drag.js +6 -4
  24. package/dist/components/TopPanel.js +2 -1
  25. package/dist/components/composition-drop-preview.d.ts +33 -0
  26. package/dist/components/composition-drop-preview.js +67 -0
  27. package/dist/components/drop-handler-data.d.ts +1 -1
  28. package/dist/components/drop-handler-data.js +27 -60
  29. package/dist/components/effect-drag-and-drop.d.ts +1 -1
  30. package/dist/components/effect-drag-and-drop.js +7 -55
  31. package/dist/components/element-drag-and-drop.d.ts +1 -1
  32. package/dist/components/element-drag-and-drop.js +5 -17
  33. package/dist/components/handle-drop.js +0 -1
  34. package/dist/components/import-assets.d.ts +7 -8
  35. package/dist/components/import-assets.js +2 -9
  36. package/dist/esm/{chunk-7a6q9hk2.js → chunk-pk1zwsn1.js} +3549 -2482
  37. package/dist/esm/internals.mjs +3549 -2482
  38. package/dist/esm/previewEntry.mjs +8342 -7275
  39. package/dist/esm/renderEntry.mjs +1 -1
  40. package/dist/helpers/get-effective-translation.d.ts +13 -1
  41. package/dist/helpers/get-effective-translation.js +12 -6
  42. package/dist/helpers/ruler-canvas-size.d.ts +7 -0
  43. package/dist/helpers/ruler-canvas-size.js +14 -1
  44. package/dist/helpers/use-image-metadata.d.ts +1 -0
  45. package/dist/helpers/use-image-metadata.js +8 -5
  46. package/dist/helpers/use-media-metadata.d.ts +1 -0
  47. package/dist/helpers/use-media-metadata.js +8 -5
  48. package/package.json +13 -12
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.AssetFolderTree = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
- const studio_shared_1 = require("@remotion/studio-shared");
38
+ const drag_and_drop_1 = require("@remotion/drag-and-drop");
39
39
  const react_1 = require("react");
40
40
  const remotion_1 = require("remotion");
41
41
  const no_react_1 = require("remotion/no-react");
@@ -49,6 +49,8 @@ const mobile_layout_1 = require("../helpers/mobile-layout");
49
49
  const sidebar_scroll_into_view_1 = require("../helpers/sidebar-scroll-into-view");
50
50
  const url_state_1 = require("../helpers/url-state");
51
51
  const use_asset_drag_events_1 = __importStar(require("../helpers/use-asset-drag-events"));
52
+ const use_image_metadata_1 = require("../helpers/use-image-metadata");
53
+ const use_media_metadata_1 = require("../helpers/use-media-metadata");
52
54
  const clipboard_1 = require("../icons/clipboard");
53
55
  const folder_1 = require("../icons/folder");
54
56
  const modals_1 = require("../state/modals");
@@ -224,14 +226,40 @@ const AssetSelectorItem = ({ item, tabIndex, level, parentFolder, readOnlyStudio
224
226
  setSidebarCollapsedState,
225
227
  ]);
226
228
  const onDragStart = (0, react_1.useCallback)((e) => {
229
+ var _a, _b, _c, _d;
227
230
  if (!canDragAsset) {
228
231
  e.preventDefault();
229
232
  return;
230
233
  }
231
234
  setIsDragging(true);
232
235
  e.dataTransfer.effectAllowed = 'copy';
233
- e.dataTransfer.setData(studio_shared_1.ASSET_DRAG_MIME_TYPE, JSON.stringify((0, studio_shared_1.makeAssetDragData)(relativePath)));
234
- }, [canDragAsset, relativePath]);
236
+ const src = (0, remotion_1.staticFile)(relativePath);
237
+ const imageMetadata = previewFileType === 'image' ? (0, use_image_metadata_1.getCachedImageMetadata)(src) : null;
238
+ const mediaMetadata = previewFileType === 'audio' || previewFileType === 'video'
239
+ ? (0, use_media_metadata_1.getCachedMediaMetadata)(src)
240
+ : null;
241
+ const width = (_b = (_a = imageMetadata === null || imageMetadata === void 0 ? void 0 : imageMetadata.width) !== null && _a !== void 0 ? _a : mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.width) !== null && _b !== void 0 ? _b : null;
242
+ const height = (_d = (_c = imageMetadata === null || imageMetadata === void 0 ? void 0 : imageMetadata.height) !== null && _c !== void 0 ? _c : mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.height) !== null && _d !== void 0 ? _d : null;
243
+ const hasDimensions = width !== null &&
244
+ height !== null &&
245
+ Number.isInteger(width) &&
246
+ Number.isInteger(height) &&
247
+ width > 0 &&
248
+ height > 0;
249
+ const durationInSeconds = (mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.duration) !== undefined &&
250
+ Number.isFinite(mediaMetadata.duration) &&
251
+ mediaMetadata.duration > 0
252
+ ? mediaMetadata.duration
253
+ : null;
254
+ const dragData = drag_and_drop_1.DragAndDropInternals.makeDragData({
255
+ type: 'asset',
256
+ assetPath: relativePath,
257
+ width: hasDimensions ? width : null,
258
+ height: hasDimensions ? height : null,
259
+ durationInSeconds,
260
+ });
261
+ e.dataTransfer.setData(dragData.mimeType, dragData.payload);
262
+ }, [canDragAsset, previewFileType, relativePath]);
235
263
  const onDragEnd = (0, react_1.useCallback)(() => {
236
264
  setIsDragging(false);
237
265
  }, []);
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Canvas = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const drag_and_drop_1 = require("@remotion/drag-and-drop");
8
9
  const react_1 = require("react");
9
10
  const remotion_1 = require("remotion");
10
11
  const get_static_files_1 = require("../api/get-static-files");
@@ -22,8 +23,10 @@ const studio_fit_padding_1 = require("../helpers/studio-fit-padding");
22
23
  const use_keybinding_1 = require("../helpers/use-keybinding");
23
24
  const canvas_ref_1 = require("../state/canvas-ref");
24
25
  const editor_guides_1 = require("../state/editor-guides");
26
+ const editor_snapping_1 = require("../state/editor-snapping");
25
27
  const editor_zoom_gestures_1 = require("../state/editor-zoom-gestures");
26
28
  const call_api_1 = require("./call-api");
29
+ const composition_drop_preview_1 = require("./composition-drop-preview");
27
30
  const ConfirmationDialog_1 = require("./ConfirmationDialog");
28
31
  const drop_handler_data_1 = require("./drop-handler-data");
29
32
  const EditorGuides_1 = __importDefault(require("./EditorGuides"));
@@ -37,6 +40,7 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
37
40
  const Preview_1 = require("./Preview");
38
41
  const ResetZoomButton_1 = require("./ResetZoomButton");
39
42
  const SvgImportDialog_1 = require("./SvgImportDialog");
43
+ const imperative_state_1 = require("./Timeline/imperative-state");
40
44
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
41
45
  const elementInstallCompositionIdStyle = {
42
46
  fontFamily: 'monospace',
@@ -100,7 +104,7 @@ const calculateCanvasScale = ({ addFitPadding, canvasSize, compositionHeight, co
100
104
  ? (0, studio_fit_padding_1.calculateStudioScale)(options)
101
105
  : remotion_1.Internals.calculateScale(options);
102
106
  };
103
- const getDropPosition = ({ addFitPadding, clientX, clientY, contentDimensions, previewSize, size, }) => {
107
+ const getDropPosition = ({ addFitPadding, clientX, clientY, contentDimensions, unbounded, previewSize, size, }) => {
104
108
  if (contentDimensions === null || contentDimensions === 'none') {
105
109
  return null;
106
110
  }
@@ -111,7 +115,10 @@ const getDropPosition = ({ addFitPadding, clientX, clientY, contentDimensions, p
111
115
  compositionWidth: contentDimensions.width,
112
116
  previewSize: previewSize.size,
113
117
  });
114
- const { centerX, centerY } = (0, get_effective_translation_1.getCenterPointWhileScrolling)({
118
+ const getCenterPoint = unbounded
119
+ ? get_effective_translation_1.getUnboundedCenterPointWhileScrolling
120
+ : get_effective_translation_1.getCenterPointWhileScrolling;
121
+ const { centerX, centerY } = getCenterPoint({
115
122
  size,
116
123
  clientX,
117
124
  clientY,
@@ -155,12 +162,14 @@ const Canvas = ({ canvasContent, size }) => {
155
162
  const config = remotion_1.Internals.useUnsafeVideoConfig();
156
163
  const areRulersVisible = (0, use_is_ruler_visible_1.useIsRulerVisible)();
157
164
  const { editorShowGuides } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
165
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
158
166
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
159
167
  const { previewServerState, subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
160
168
  const previewServerClientId = previewServerState.type === 'connected'
161
169
  ? previewServerState.clientId
162
170
  : null;
163
171
  const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
172
+ const [compositionDropPreview, setCompositionDropPreview] = (0, react_1.useState)(null);
164
173
  const [installingElementName, setInstallingElementName] = (0, react_1.useState)(null);
165
174
  const [pendingElementInstallRequests, setPendingElementInstallRequests] = (0, react_1.useState)([]);
166
175
  const [activeElementInstallRequest, setActiveElementInstallRequest] = (0, react_1.useState)(null);
@@ -696,18 +705,109 @@ const Canvas = ({ canvasContent, size }) => {
696
705
  };
697
706
  }, [activeElementInstallRequest, confirm]);
698
707
  const onDragOver = (0, react_1.useCallback)((event) => {
708
+ var _a;
709
+ var _b;
699
710
  if (!(0, drop_handler_data_1.isSupportedDropEvent)(event) || !isDragEventInsideCanvas(event)) {
711
+ setCompositionDropPreview(null);
700
712
  return;
701
713
  }
702
714
  if (!canDropAssets && !cannotAddSequence) {
715
+ setCompositionDropPreview(null);
703
716
  return;
704
717
  }
705
718
  event.preventDefault();
706
719
  if (event.dataTransfer) {
707
720
  event.dataTransfer.dropEffect = canDropAssets ? 'copy' : 'none';
708
721
  }
709
- }, [canDropAssets, cannotAddSequence]);
722
+ if (!canDropAssets ||
723
+ contentDimensions === null ||
724
+ contentDimensions === 'none') {
725
+ setCompositionDropPreview(null);
726
+ return;
727
+ }
728
+ const metadata = drag_and_drop_1.DragAndDropInternals.getDragPreviewMetadata((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []);
729
+ if ((metadata === null || metadata === void 0 ? void 0 : metadata.type) !== 'composition' ||
730
+ metadata.width === undefined ||
731
+ metadata.height === undefined) {
732
+ setCompositionDropPreview(null);
733
+ return;
734
+ }
735
+ let dropPosition = getDropPosition({
736
+ addFitPadding,
737
+ clientX: event.clientX,
738
+ clientY: event.clientY,
739
+ contentDimensions,
740
+ unbounded: true,
741
+ previewSize,
742
+ size,
743
+ });
744
+ if (dropPosition === null) {
745
+ setCompositionDropPreview(null);
746
+ return;
747
+ }
748
+ const compositionDimensions = {
749
+ width: metadata.width,
750
+ height: metadata.height,
751
+ };
752
+ if (editorSnapping && !event.metaKey && !event.ctrlKey) {
753
+ dropPosition = (0, composition_drop_preview_1.snapCompositionDropPosition)({
754
+ compositionDimensions,
755
+ destinationDimensions: contentDimensions,
756
+ dropPosition,
757
+ scale: calculateCanvasScale({
758
+ addFitPadding,
759
+ canvasSize: size,
760
+ compositionHeight: contentDimensions.height,
761
+ compositionWidth: contentDimensions.width,
762
+ previewSize: previewSize.size,
763
+ }),
764
+ });
765
+ }
766
+ setCompositionDropPreview((currentPreview) => {
767
+ if ((currentPreview === null || currentPreview === void 0 ? void 0 : currentPreview.compositionDimensions.width) ===
768
+ compositionDimensions.width &&
769
+ currentPreview.compositionDimensions.height ===
770
+ compositionDimensions.height &&
771
+ currentPreview.dropPosition.centerX === dropPosition.centerX &&
772
+ currentPreview.dropPosition.centerY === dropPosition.centerY) {
773
+ return currentPreview;
774
+ }
775
+ return {
776
+ compositionDimensions,
777
+ dropPosition,
778
+ };
779
+ });
780
+ }, [
781
+ addFitPadding,
782
+ canDropAssets,
783
+ cannotAddSequence,
784
+ contentDimensions,
785
+ editorSnapping,
786
+ previewSize,
787
+ size,
788
+ ]);
789
+ const onDragLeave = (0, react_1.useCallback)((event) => {
790
+ const canvas = canvas_ref_1.canvasRef.current;
791
+ if (canvas !== null) {
792
+ const rect = canvas.getBoundingClientRect();
793
+ if ((event.clientX >= rect.left &&
794
+ event.clientX <= rect.right &&
795
+ event.clientY >= rect.top &&
796
+ event.clientY <= rect.bottom) ||
797
+ (event.relatedTarget instanceof Node &&
798
+ canvas.contains(event.relatedTarget))) {
799
+ return;
800
+ }
801
+ }
802
+ setCompositionDropPreview(null);
803
+ }, []);
804
+ const onDragEnd = (0, react_1.useCallback)(() => {
805
+ setCompositionDropPreview(null);
806
+ }, []);
710
807
  const onDrop = (0, react_1.useCallback)(async (event) => {
808
+ var _a;
809
+ var _b;
810
+ setCompositionDropPreview(null);
711
811
  if (!(0, drop_handler_data_1.isSupportedDropEvent)(event) || !isDragEventInsideCanvas(event)) {
712
812
  return;
713
813
  }
@@ -732,14 +832,42 @@ const Canvas = ({ canvasContent, size }) => {
732
832
  event.stopPropagation();
733
833
  setIsAddingAsset(true);
734
834
  try {
735
- const dropPosition = getDropPosition({
835
+ const metadata = drag_and_drop_1.DragAndDropInternals.getDragPreviewMetadata((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types) !== null && _b !== void 0 ? _b : []);
836
+ const isComposition = (metadata === null || metadata === void 0 ? void 0 : metadata.type) === 'composition';
837
+ let dropPosition = getDropPosition({
736
838
  addFitPadding,
737
839
  clientX: event.clientX,
738
840
  clientY: event.clientY,
739
841
  contentDimensions,
842
+ unbounded: isComposition,
740
843
  previewSize,
741
844
  size,
742
845
  });
846
+ if (dropPosition !== null &&
847
+ isComposition &&
848
+ metadata.width !== undefined &&
849
+ metadata.height !== undefined &&
850
+ contentDimensions !== null &&
851
+ contentDimensions !== 'none' &&
852
+ editorSnapping &&
853
+ !event.metaKey &&
854
+ !event.ctrlKey) {
855
+ dropPosition = (0, composition_drop_preview_1.snapCompositionDropPosition)({
856
+ compositionDimensions: {
857
+ width: metadata.width,
858
+ height: metadata.height,
859
+ },
860
+ destinationDimensions: contentDimensions,
861
+ dropPosition,
862
+ scale: calculateCanvasScale({
863
+ addFitPadding,
864
+ canvasSize: size,
865
+ compositionHeight: contentDimensions.height,
866
+ compositionWidth: contentDimensions.width,
867
+ previewSize: previewSize.size,
868
+ }),
869
+ });
870
+ }
743
871
  await (0, handle_drop_1.handleDrop)({
744
872
  chooseSvgImportMode,
745
873
  compositionFile,
@@ -748,7 +876,7 @@ const Canvas = ({ canvasContent, size }) => {
748
876
  dropPosition,
749
877
  event,
750
878
  fps: config.fps,
751
- from: null,
879
+ from: (0, imperative_state_1.getCurrentFrame)(),
752
880
  });
753
881
  }
754
882
  finally {
@@ -763,6 +891,7 @@ const Canvas = ({ canvasContent, size }) => {
763
891
  config,
764
892
  contentDimensions,
765
893
  currentCompositionId,
894
+ editorSnapping,
766
895
  previewSize,
767
896
  size,
768
897
  ]);
@@ -861,12 +990,16 @@ const Canvas = ({ canvasContent, size }) => {
861
990
  ]);
862
991
  (0, react_1.useEffect)(() => {
863
992
  document.addEventListener('dragover', onDragOver, { capture: true });
993
+ document.addEventListener('dragleave', onDragLeave, { capture: true });
994
+ document.addEventListener('dragend', onDragEnd, { capture: true });
864
995
  document.addEventListener('drop', onDrop, { capture: true });
865
996
  return () => {
866
997
  document.removeEventListener('dragover', onDragOver, { capture: true });
998
+ document.removeEventListener('dragleave', onDragLeave, { capture: true });
999
+ document.removeEventListener('dragend', onDragEnd, { capture: true });
867
1000
  document.removeEventListener('drop', onDrop, { capture: true });
868
1001
  };
869
- }, [onDragOver, onDrop]);
1002
+ }, [onDragEnd, onDragLeave, onDragOver, onDrop]);
870
1003
  (0, react_1.useEffect)(() => {
871
1004
  if (!canDropAssets ||
872
1005
  !keybindings.isHighestContext ||
@@ -876,7 +1009,29 @@ const Canvas = ({ canvasContent, size }) => {
876
1009
  document.addEventListener('paste', onPaste);
877
1010
  return () => document.removeEventListener('paste', onPaste);
878
1011
  }, [canDropAssets, keybindings.isHighestContext, onPaste]);
1012
+ const compositionDropPreviewStyle = (0, react_1.useMemo)(() => {
1013
+ if (compositionDropPreview === null ||
1014
+ contentDimensions === null ||
1015
+ contentDimensions === 'none') {
1016
+ return null;
1017
+ }
1018
+ const box = (0, composition_drop_preview_1.getCompositionDropPreviewBox)({
1019
+ canvasSize: size,
1020
+ destinationDimensions: contentDimensions,
1021
+ preview: compositionDropPreview,
1022
+ previewSize,
1023
+ });
1024
+ return {
1025
+ ...box,
1026
+ position: 'absolute',
1027
+ boxSizing: 'border-box',
1028
+ border: colors_1.BORDER_TIMELINE_DROP_BLUE,
1029
+ backgroundColor: colors_1.TIMELINE_DROP_BLUE_ALPHA_16,
1030
+ pointerEvents: 'none',
1031
+ zIndex: 1,
1032
+ };
1033
+ }, [compositionDropPreview, contentDimensions, previewSize, size]);
879
1034
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
880
- jsx_runtime_1.jsxs("div", { ref: canvas_ref_1.canvasRef, style: getContainerStyle(editorZoomGestures), children: [size ? (jsx_runtime_1.jsx(Preview_1.VideoPreview, { canvasContent: canvasContent, contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, onRetryAssetMetadata: fetchMetadata })) : null, isFit ? null : (jsx_runtime_1.jsx("div", { style: resetZoom, className: "css-reset", children: jsx_runtime_1.jsx(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) })), editorShowGuides && canvasContent.type === 'composition' && (jsx_runtime_1.jsx(EditorGuides_1.default, { canvasSize: size, contentDimensions: contentDimensions, assetMetadata: assetResolution }))] }), areRulersVisible && (jsx_runtime_1.jsx(EditorRuler_1.EditorRulers, { contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, containerRef: canvas_ref_1.canvasRef }))] }));
1035
+ jsx_runtime_1.jsxs("div", { ref: canvas_ref_1.canvasRef, style: getContainerStyle(editorZoomGestures), children: [size ? (jsx_runtime_1.jsx(Preview_1.VideoPreview, { canvasContent: canvasContent, contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, onRetryAssetMetadata: fetchMetadata })) : null, compositionDropPreviewStyle === null ? null : (jsx_runtime_1.jsx("div", { className: "css-reset", "data-testid": "composition-drop-preview", style: compositionDropPreviewStyle })), isFit ? null : (jsx_runtime_1.jsx("div", { style: resetZoom, className: "css-reset", children: jsx_runtime_1.jsx(ResetZoomButton_1.ResetZoomButton, { onClick: onReset }) })), editorShowGuides && canvasContent.type === 'composition' && (jsx_runtime_1.jsx(EditorGuides_1.default, { canvasSize: size, contentDimensions: contentDimensions, assetMetadata: assetResolution }))] }), areRulersVisible && (jsx_runtime_1.jsx(EditorRuler_1.EditorRulers, { contentDimensions: contentDimensions, canvasSize: size, assetMetadata: assetResolution, containerRef: canvas_ref_1.canvasRef }))] }));
881
1036
  };
882
1037
  exports.Canvas = Canvas;
@@ -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 drag_and_drop_1 = require("@remotion/drag-and-drop");
5
6
  const studio_shared_1 = require("@remotion/studio-shared");
6
7
  const react_1 = require("react");
7
8
  const remotion_1 = require("remotion");
@@ -188,8 +189,9 @@ const CompositionSelector = () => {
188
189
  }
189
190
  }, [runCompositionListAutoScroll, stopCompositionListAutoScroll]);
190
191
  const onCompositionListDragOverCapture = (0, react_1.useCallback)((event) => {
192
+ var _a;
191
193
  if (window.remotion_isReadOnlyStudio ||
192
- !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
194
+ ((_a = drag_and_drop_1.DragAndDropInternals.getDragPreviewMetadata(event.dataTransfer.types)) === null || _a === void 0 ? void 0 : _a.type) !== 'composition') {
193
195
  stopCompositionListAutoScroll();
194
196
  return;
195
197
  }
@@ -204,8 +206,9 @@ const CompositionSelector = () => {
204
206
  return stopCompositionListAutoScroll;
205
207
  }, [stopCompositionListAutoScroll]);
206
208
  const onRootDragOver = (0, react_1.useCallback)((event) => {
209
+ var _a;
207
210
  if (window.remotion_isReadOnlyStudio ||
208
- !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
211
+ ((_a = drag_and_drop_1.DragAndDropInternals.getDragPreviewMetadata(event.dataTransfer.types)) === null || _a === void 0 ? void 0 : _a.type) !== 'composition') {
209
212
  return;
210
213
  }
211
214
  event.preventDefault();
@@ -225,35 +228,35 @@ const CompositionSelector = () => {
225
228
  if (window.remotion_isReadOnlyStudio) {
226
229
  return;
227
230
  }
228
- const raw = event.dataTransfer.getData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
229
- const parsed = raw ? (0, studio_shared_1.parseCompositionDragData)(raw) : null;
230
- if (parsed === null) {
231
+ const parsed = drag_and_drop_1.DragAndDropInternals.parseDragData(event.dataTransfer);
232
+ if ((parsed === null || parsed === void 0 ? void 0 : parsed.type) !== 'composition') {
231
233
  return;
232
234
  }
235
+ const compositionDragData = parsed.data;
233
236
  event.preventDefault();
234
237
  event.stopPropagation();
235
238
  stopCompositionListAutoScroll();
236
239
  setRootDragHovered(false);
237
- const composition = compositions.find((c) => c.id === parsed.compositionId);
240
+ const composition = compositions.find((c) => c.id === compositionDragData.compositionId);
238
241
  if (!composition || composition.folderName === null) {
239
242
  return;
240
243
  }
241
- const notification = (0, NotificationCenter_1.showNotification)(`Moving ${parsed.compositionId}...`, null);
244
+ const notification = (0, NotificationCenter_1.showNotification)(`Moving ${compositionDragData.compositionId}...`, null);
242
245
  const controller = new AbortController();
243
246
  try {
244
247
  const result = await (0, actions_1.applyCodemod)({
245
248
  codemod: {
246
249
  type: 'move-composition-to-folder',
247
- idToMove: parsed.compositionId,
250
+ idToMove: compositionDragData.compositionId,
248
251
  folderName: null,
249
252
  parentName: null,
250
253
  },
251
254
  dryRun: false,
252
255
  signal: controller.signal,
253
- symbolicatedStack: (0, studio_shared_1.compositionDragDataToSymbolicatedStack)(parsed),
256
+ symbolicatedStack: (0, studio_shared_1.compositionDragDataToSymbolicatedStack)(compositionDragData),
254
257
  });
255
258
  notification.replaceContent(result.success
256
- ? `Moved ${parsed.compositionId} outside of folder`
259
+ ? `Moved ${compositionDragData.compositionId} outside of folder`
257
260
  : result.reason, result.success ? 2000 : 4000);
258
261
  }
259
262
  catch (err) {
@@ -2,6 +2,7 @@
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 drag_and_drop_1 = require("@remotion/drag-and-drop");
5
6
  const studio_shared_1 = require("@remotion/studio-shared");
6
7
  const react_1 = require("react");
7
8
  const client_id_1 = require("../helpers/client-id");
@@ -142,25 +143,31 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
142
143
  });
143
144
  }, [connectionStatus, item, resolvedLocation, setSelectedModal]);
144
145
  const onCompositionDragStart = (0, react_1.useCallback)((event) => {
145
- var _a;
146
+ var _a, _b, _c, _d;
146
147
  if (item.type !== 'composition' || window.remotion_isReadOnlyStudio) {
147
148
  event.preventDefault();
148
149
  return;
149
150
  }
150
151
  setIsDragging(true);
151
152
  event.dataTransfer.effectAllowed = 'copyMove';
152
- event.dataTransfer.setData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE, JSON.stringify((0, studio_shared_1.makeCompositionDragData)({
153
+ const dragData = drag_and_drop_1.DragAndDropInternals.makeDragData({
154
+ type: 'composition',
153
155
  compositionFile: (_a = resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source) !== null && _a !== void 0 ? _a : null,
154
156
  compositionId: item.composition.id,
155
- })));
157
+ width: (_b = item.composition.width) !== null && _b !== void 0 ? _b : null,
158
+ height: (_c = item.composition.height) !== null && _c !== void 0 ? _c : null,
159
+ durationInFrames: (_d = item.composition.durationInFrames) !== null && _d !== void 0 ? _d : null,
160
+ });
161
+ event.dataTransfer.setData(dragData.mimeType, dragData.payload);
156
162
  }, [item, resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source]);
157
163
  const onCompositionDragEnd = (0, react_1.useCallback)(() => {
158
164
  setIsDragging(false);
159
165
  }, []);
160
166
  const onFolderDragOver = (0, react_1.useCallback)((event) => {
167
+ var _a;
161
168
  if (item.type !== 'folder' ||
162
169
  window.remotion_isReadOnlyStudio ||
163
- !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
170
+ ((_a = drag_and_drop_1.DragAndDropInternals.getDragPreviewMetadata(event.dataTransfer.types)) === null || _a === void 0 ? void 0 : _a.type) !== 'composition') {
164
171
  return;
165
172
  }
166
173
  event.preventDefault();
@@ -173,9 +180,10 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
173
180
  setDragHovered(false);
174
181
  }, []);
175
182
  const onFolderChildListDragOver = (0, react_1.useCallback)((event) => {
183
+ var _a;
176
184
  if (item.type !== 'folder' ||
177
185
  window.remotion_isReadOnlyStudio ||
178
- !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
186
+ ((_a = drag_and_drop_1.DragAndDropInternals.getDragPreviewMetadata(event.dataTransfer.types)) === null || _a === void 0 ? void 0 : _a.type) !== 'composition') {
179
187
  return;
180
188
  }
181
189
  event.preventDefault();
@@ -187,18 +195,18 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
187
195
  if (item.type !== 'folder' || window.remotion_isReadOnlyStudio) {
188
196
  return;
189
197
  }
190
- const raw = event.dataTransfer.getData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
191
- const parsed = raw ? (0, studio_shared_1.parseCompositionDragData)(raw) : null;
192
- if (parsed === null) {
198
+ const parsed = drag_and_drop_1.DragAndDropInternals.parseDragData(event.dataTransfer);
199
+ if ((parsed === null || parsed === void 0 ? void 0 : parsed.type) !== 'composition') {
193
200
  return;
194
201
  }
202
+ const compositionDragData = parsed.data;
195
203
  event.preventDefault();
196
204
  event.stopPropagation();
197
205
  clearRootDragHover();
198
206
  setDragHovered(false);
199
207
  const isAlreadyDirectChild = item.items.some((child) => {
200
208
  return (child.type === 'composition' &&
201
- child.composition.id === parsed.compositionId);
209
+ child.composition.id === compositionDragData.compositionId);
202
210
  });
203
211
  if (isAlreadyDirectChild) {
204
212
  return;
@@ -207,22 +215,22 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
207
215
  folderName: item.folderName,
208
216
  parentName: item.parentName,
209
217
  });
210
- const notification = (0, NotificationCenter_1.showNotification)(`Moving ${parsed.compositionId}...`, null);
218
+ const notification = (0, NotificationCenter_1.showNotification)(`Moving ${compositionDragData.compositionId}...`, null);
211
219
  const controller = new AbortController();
212
220
  try {
213
221
  const result = await (0, actions_1.applyCodemod)({
214
222
  codemod: {
215
223
  type: 'move-composition-to-folder',
216
- idToMove: parsed.compositionId,
224
+ idToMove: compositionDragData.compositionId,
217
225
  folderName: item.folderName,
218
226
  parentName: item.parentName,
219
227
  },
220
228
  dryRun: false,
221
229
  signal: controller.signal,
222
- symbolicatedStack: (0, studio_shared_1.compositionDragDataToSymbolicatedStack)(parsed),
230
+ symbolicatedStack: (0, studio_shared_1.compositionDragDataToSymbolicatedStack)(compositionDragData),
223
231
  });
224
232
  notification.replaceContent(result.success
225
- ? `Moved ${parsed.compositionId} to ${folderId}`
233
+ ? `Moved ${compositionDragData.compositionId} to ${folderId}`
226
234
  : result.reason, result.success ? 2000 : 4000);
227
235
  if (result.success && !item.expanded) {
228
236
  toggleFolder(item.folderName, item.parentName);
@@ -35,7 +35,7 @@ const StudioClearSelectionArea = ({ children }) => {
35
35
  const EditorContent = ({ readOnlyStudio, children }) => {
36
36
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
37
37
  const showTimeline = canvasContent !== null && canvasContent.type === 'composition';
38
- const content = (jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, children: [
38
+ const content = (jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, maxFlexerSize: null, maxAntiFlexerSize: null, children: [
39
39
  jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: showTimeline ? jsx_runtime_1.jsx(Timeline_1.Timeline, {}) : jsx_runtime_1.jsx(TimelineEmptyState_1.TimelineEmptyState, {}) })
40
40
  ] }));
41
41
  return (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionProvider, { children: jsx_runtime_1.jsxs(StudioClearSelectionArea, { children: [
@@ -6,8 +6,8 @@ const remotion_1 = require("remotion");
6
6
  const colors_1 = require("../../helpers/colors");
7
7
  const editor_guide_selection_1 = require("../../helpers/editor-guide-selection");
8
8
  const editor_ruler_1 = require("../../helpers/editor-ruler");
9
+ const ruler_canvas_size_1 = require("../../helpers/ruler-canvas-size");
9
10
  const editor_guides_1 = require("../../state/editor-guides");
10
- const editor_rulers_1 = require("../../state/editor-rulers");
11
11
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
12
12
  const should_clear_selection_on_pointer_down_1 = require("../Timeline/should-clear-selection-on-pointer-down");
13
13
  const TimelineSelection_1 = require("../Timeline/TimelineSelection");
@@ -30,8 +30,10 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
30
30
  hoveredGuideId,
31
31
  draggingGuideId,
32
32
  }), [draggingGuideId, guidesList, hoveredGuideId, selectedItems]);
33
- const rulerWidth = isVerticalRuler ? editor_rulers_1.RULER_WIDTH : size.width - editor_rulers_1.RULER_WIDTH;
34
- const rulerHeight = isVerticalRuler ? size.height - editor_rulers_1.RULER_WIDTH : editor_rulers_1.RULER_WIDTH;
33
+ const { width: rulerWidth, height: rulerHeight } = (0, ruler_canvas_size_1.getRulerCanvasSize)({
34
+ orientation,
35
+ size,
36
+ });
35
37
  (0, react_1.useEffect)(() => {
36
38
  (0, editor_ruler_1.drawMarkingOnRulerCanvas)({
37
39
  scale,
@@ -37,17 +37,29 @@ exports.ForceSpecificCursor = exports.stopForcingSpecificCursor = exports.forceS
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const ref = react_1.default.createRef();
40
+ const removeAutomaticCleanupListeners = () => {
41
+ window.removeEventListener('pointerup', exports.stopForcingSpecificCursor, true);
42
+ window.removeEventListener('pointercancel', exports.stopForcingSpecificCursor, true);
43
+ window.removeEventListener('blur', exports.stopForcingSpecificCursor, true);
44
+ };
40
45
  const forceSpecificCursor = (cursor) => {
41
46
  if (!ref.current) {
42
47
  throw new Error('ForceSpecificCursor is not mounted');
43
48
  }
44
49
  ref.current.style.cursor = cursor;
45
50
  ref.current.style.pointerEvents = 'auto';
51
+ // The component which initiated the drag may unmount before it gets a chance
52
+ // to handle the end of the gesture. Keep this fallback independent from the
53
+ // initiator so the cursor overlay can never remain stuck.
54
+ window.addEventListener('pointerup', exports.stopForcingSpecificCursor, true);
55
+ window.addEventListener('pointercancel', exports.stopForcingSpecificCursor, true);
56
+ window.addEventListener('blur', exports.stopForcingSpecificCursor, true);
46
57
  };
47
58
  exports.forceSpecificCursor = forceSpecificCursor;
48
59
  const stopForcingSpecificCursor = () => {
60
+ removeAutomaticCleanupListeners();
49
61
  if (!ref.current) {
50
- throw new Error('ForceSpecificCursor is not mounted');
62
+ return;
51
63
  }
52
64
  ref.current.style.cursor = '';
53
65
  ref.current.style.pointerEvents = 'none';
@@ -1,7 +1,33 @@
1
1
  import type { InputHTMLAttributes } from 'react';
2
2
  import React from 'react';
3
3
  import type { RemInputStatus } from './RemInput';
4
+ type InputDraggerValidationResult = {
5
+ readonly valid: true;
6
+ readonly value: number;
7
+ } | {
8
+ readonly valid: false;
9
+ readonly message: string;
10
+ };
4
11
  export declare const inputDraggerContainerStyle: React.CSSProperties;
12
+ export declare const parseInputDraggerNumber: (value: string) => number | null;
13
+ export declare const isInputDraggerValueAlignedToStep: ({ min, step, value, }: {
14
+ readonly min: string | number | undefined;
15
+ readonly step: string | number | undefined;
16
+ readonly value: number;
17
+ }) => boolean;
18
+ export declare const validateInputDraggerValue: ({ max, min, step, value, }: {
19
+ readonly max: string | number | undefined;
20
+ readonly min: string | number | undefined;
21
+ readonly step: string | number | undefined;
22
+ readonly value: string;
23
+ }) => InputDraggerValidationResult;
24
+ export declare const deriveInputDraggerArrowValue: ({ direction, max, min, step, value, }: {
25
+ readonly direction: -1 | 1;
26
+ readonly max: string | number | undefined;
27
+ readonly min: string | number | undefined;
28
+ readonly step: string | number | undefined;
29
+ readonly value: number;
30
+ }) => number;
5
31
  export declare const deriveInputDraggerStep: ({ min, snapToStep, step, }: {
6
32
  readonly min: string | number | undefined;
7
33
  readonly snapToStep: boolean;
@@ -33,3 +59,4 @@ export declare const InputDragger: React.ForwardRefExoticComponent<InputHTMLAttr
33
59
  readonly dragDecimalPlaces?: number | undefined;
34
60
  readonly dragSensitivity?: number | undefined;
35
61
  } & React.RefAttributes<HTMLButtonElement>>;
62
+ export {};