@remotion/studio 4.0.496 → 4.0.497

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 (81) hide show
  1. package/dist/components/AudioWaveform.js +1 -11
  2. package/dist/components/Canvas.js +22 -203
  3. package/dist/components/CompositionSelectorItem.js +2 -10
  4. package/dist/components/InspectorPanel/AlignmentControls.js +2 -0
  5. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +27 -2
  6. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +65 -8
  7. package/dist/components/InspectorPanel/use-composition-actions.js +6 -2
  8. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -1
  9. package/dist/components/NewComposition/CodemodFooter.js +23 -4
  10. package/dist/components/NewComposition/InputDragger.d.ts +6 -0
  11. package/dist/components/NewComposition/InputDragger.js +12 -3
  12. package/dist/components/NewComposition/NewComposition.js +1 -1
  13. package/dist/components/NewComposition/use-rename-static-file.js +1 -1
  14. package/dist/components/SelectedOutlineElement.js +56 -88
  15. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  16. package/dist/components/SelectedOutlineOverlay.js +9 -10
  17. package/dist/components/Timeline/Timeline.js +10 -3
  18. package/dist/components/Timeline/TimelineAssetDropIndicator.d.ts +2 -0
  19. package/dist/components/Timeline/TimelineAssetDropIndicator.js +37 -0
  20. package/dist/components/Timeline/TimelineClipboardKeybindings.js +1 -7
  21. package/dist/components/Timeline/TimelineScrollable.js +3 -2
  22. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  23. package/dist/components/Timeline/TimelineSelection.js +40 -5
  24. package/dist/components/Timeline/TimelineSequence.js +20 -8
  25. package/dist/components/Timeline/TimelineSequenceFrame.js +2 -4
  26. package/dist/components/Timeline/TimelineSequenceItem.js +2 -0
  27. package/dist/components/Timeline/TimelineSequencePropItem.js +4 -0
  28. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +15 -3
  29. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +96 -18
  30. package/dist/components/Timeline/TimelineTimeIndicators.d.ts +16 -0
  31. package/dist/components/Timeline/TimelineTimeIndicators.js +154 -35
  32. package/dist/components/Timeline/TimelineTranslateField.js +2 -1
  33. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  34. package/dist/components/Timeline/TimelineVideoInfo.js +4 -1
  35. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +2 -0
  36. package/dist/components/Timeline/delete-selected-timeline-item.js +5 -4
  37. package/dist/components/Timeline/disable-sequence-interactivity.js +2 -0
  38. package/dist/components/Timeline/get-timeline-media-visualization-layout.d.ts +8 -0
  39. package/dist/components/Timeline/get-timeline-media-visualization-layout.js +10 -0
  40. package/dist/components/Timeline/get-timeline-video-info-widths.js +11 -3
  41. package/dist/components/Timeline/keyframe-clipboard.js +21 -5
  42. package/dist/components/Timeline/reset-selected-timeline-props.js +2 -0
  43. package/dist/components/Timeline/save-sequence-prop.d.ts +5 -3
  44. package/dist/components/Timeline/save-sequence-prop.js +43 -18
  45. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  46. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +1 -1
  47. package/dist/components/Timeline/timeline-asset-drop-context.d.ts +1 -0
  48. package/dist/components/Timeline/timeline-asset-drop-context.js +5 -0
  49. package/dist/components/Timeline/timeline-scroll-logic.d.ts +7 -0
  50. package/dist/components/Timeline/timeline-scroll-logic.js +10 -1
  51. package/dist/components/Timeline/use-rename-sequence.js +2 -0
  52. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +2 -0
  53. package/dist/components/Timeline/use-timeline-asset-drop.d.ts +1 -0
  54. package/dist/components/Timeline/use-timeline-asset-drop.js +168 -0
  55. package/dist/components/composition-menu-items.d.ts +15 -1
  56. package/dist/components/composition-menu-items.js +137 -107
  57. package/dist/components/drop-handler-data.d.ts +13 -0
  58. package/dist/components/drop-handler-data.js +117 -0
  59. package/dist/components/handle-drop.d.ts +13 -0
  60. package/dist/components/handle-drop.js +115 -0
  61. package/dist/components/import-assets.d.ts +26 -8
  62. package/dist/components/import-assets.js +161 -49
  63. package/dist/components/selected-outline-drag.d.ts +11 -1
  64. package/dist/components/selected-outline-drag.js +74 -1
  65. package/dist/esm/{chunk-0v4n7nkh.js → chunk-5wj95bdd.js} +4262 -3392
  66. package/dist/esm/internals.mjs +4262 -3392
  67. package/dist/esm/previewEntry.mjs +4464 -3594
  68. package/dist/esm/renderEntry.mjs +1 -1
  69. package/dist/helpers/is-video-with-last-frame-hold.d.ts +2 -0
  70. package/dist/helpers/is-video-with-last-frame-hold.js +9 -0
  71. package/dist/helpers/url-state.d.ts +1 -0
  72. package/dist/helpers/url-state.js +5 -1
  73. package/dist/helpers/use-max-media-duration.js +5 -3
  74. package/dist/helpers/use-menu-structure.js +2 -0
  75. package/dist/icons/duplicate.d.ts +5 -0
  76. package/dist/icons/duplicate.js +10 -0
  77. package/dist/icons/snowflake.d.ts +5 -0
  78. package/dist/icons/snowflake.js +10 -0
  79. package/dist/icons/trash.d.ts +5 -0
  80. package/dist/icons/trash.js +8 -0
  81. package/package.json +11 -11
@@ -16,6 +16,11 @@ export declare const isInputDraggerValueInRange: ({ max, min, value, }: {
16
16
  readonly min: string | number | undefined;
17
17
  readonly value: number;
18
18
  }) => boolean;
19
+ export declare const deriveInputDraggerValueDiff: ({ dragSensitivity, step, xDistance, }: {
20
+ readonly dragSensitivity: number;
21
+ readonly step: number;
22
+ readonly xDistance: number;
23
+ }) => number;
19
24
  export declare const InputDragger: React.ForwardRefExoticComponent<InputHTMLAttributes<HTMLInputElement> & {
20
25
  readonly onValueChange: (newVal: number) => void;
21
26
  readonly onValueChangeEnd?: ((newVal: number) => void) | undefined;
@@ -26,4 +31,5 @@ export declare const InputDragger: React.ForwardRefExoticComponent<InputHTMLAttr
26
31
  readonly small?: boolean | undefined;
27
32
  readonly snapToStep?: boolean | undefined;
28
33
  readonly dragDecimalPlaces?: number | undefined;
34
+ readonly dragSensitivity?: number | undefined;
29
35
  } & React.RefAttributes<HTMLButtonElement>>;
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.InputDragger = exports.isInputDraggerValueInRange = exports.deriveInputDraggerDragStartValue = exports.deriveInputDraggerStep = exports.inputDraggerContainerStyle = void 0;
36
+ exports.InputDragger = exports.deriveInputDraggerValueDiff = exports.isInputDraggerValueInRange = exports.deriveInputDraggerDragStartValue = exports.deriveInputDraggerStep = exports.inputDraggerContainerStyle = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
@@ -92,7 +92,11 @@ const isInputDraggerValueInRange = ({ max, min, value, }) => {
92
92
  (!Number.isFinite(numericMax) || value <= numericMax));
93
93
  };
94
94
  exports.isInputDraggerValueInRange = isInputDraggerValueInRange;
95
- const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min, max: _max, step: _step, value, onTextChange, formatter = (q) => String(q), status, rightAlign, small, snapToStep = true, dragDecimalPlaces, ...props }, ref) => {
95
+ const deriveInputDraggerValueDiff = ({ dragSensitivity, step, xDistance, }) => {
96
+ return (0, remotion_1.interpolate)(xDistance, [-5, -4, 0, 4, 5], [-step * dragSensitivity, 0, 0, 0, step * dragSensitivity]);
97
+ };
98
+ exports.deriveInputDraggerValueDiff = deriveInputDraggerValueDiff;
99
+ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min, max: _max, step: _step, value, onTextChange, formatter = (q) => String(q), status, rightAlign, small, snapToStep = true, dragDecimalPlaces, dragSensitivity = 1, ...props }, ref) => {
96
100
  const [inputFallback, setInputFallback] = (0, react_1.useState)(false);
97
101
  const [dragging, setDragging] = (0, react_1.useState)(false);
98
102
  const fallbackRef = (0, react_1.useRef)(null);
@@ -195,7 +199,11 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
195
199
  (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
196
200
  target.blur();
197
201
  }
198
- const diff = (0, remotion_1.interpolate)(xDistance, [-5, -4, 0, 4, 5], [-step, 0, 0, 0, step]);
202
+ const diff = (0, exports.deriveInputDraggerValueDiff)({
203
+ dragSensitivity,
204
+ step,
205
+ xDistance,
206
+ });
199
207
  const newValue = Math.min(max, Math.max(min, dragStartValue + diff));
200
208
  const nextValue = snapToStep
201
209
  ? roundToStep(newValue, step)
@@ -229,6 +237,7 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
229
237
  onValueChangeEnd,
230
238
  snapToStep,
231
239
  dragDecimalPlaces,
240
+ dragSensitivity,
232
241
  ]);
233
242
  (0, react_1.useEffect)(() => {
234
243
  var _a;
@@ -125,7 +125,7 @@ const NewCompositionLoaded = ({ folderName, parentName, stack }) => {
125
125
  ] }), jsx_runtime_1.jsx(NewCompDuration_1.NewCompDuration, { durationInFrames: durationInFrames, setDurationInFrames: setDurationInFrames }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
126
126
  jsx_runtime_1.jsx("div", { style: layout_2.label, children: "FPS" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: selectedFrameRate, onTextChange: onTextFpsChange, placeholder: "Frame rate (fps)", name: "fps", min: 1, required: true, status: "ok", max: 240, step: 0.01, onValueChange: onFpsChange, rightAlign: false }) })
127
127
  ] })
128
- ] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: "Creating composition...", errorNotification: "Could not create composition", successNotification: `Created ${newId}`, genericSubmitLabel: "Add to root file", submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, stack: stack, valid: valid, onSuccess: null, applyCodemod: ({ signal, symbolicatedStack }) => createComposition({
128
+ ] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: null, errorNotification: "Could not create composition", successNotification: `Created ${newId}`, genericSubmitLabel: "Add to root file", submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, stack: stack, valid: valid, onSuccess: null, applyCodemod: ({ signal, symbolicatedStack }) => createComposition({
129
129
  signal,
130
130
  symbolicatedStack,
131
131
  }), fallbackToRootFile: true }) })
@@ -76,7 +76,7 @@ const useRenameStaticFile = ({ relativePath, staticFiles, }) => {
76
76
  if ((canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'asset' &&
77
77
  canvasContent.asset === relativePath) {
78
78
  setCanvasContent({ type: 'asset', asset: newRelativePath });
79
- (0, url_state_1.pushUrl)(`/assets/${newRelativePath}`);
79
+ (0, url_state_1.replaceUrl)(`/assets/${newRelativePath}`);
80
80
  }
81
81
  notification.replaceContent(`Renamed to ${newRelativePath}`, 2000);
82
82
  return true;
@@ -114,12 +114,6 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
114
114
  const [scaleX, scaleY] = no_react_1.NoReactInternals.parseScaleValue(transformOriginDrag.scaleValue);
115
115
  const startTranslate = (0, timeline_translate_utils_1.parseTranslate)(transformOriginDrag.translateValue);
116
116
  const svgRect = svg.getBoundingClientRect();
117
- const defaultOrigin = transformOriginDrag.originDefault !== undefined
118
- ? JSON.stringify(transformOriginDrag.originDefault)
119
- : null;
120
- const defaultTranslate = transformOriginDrag.translateDefault !== undefined
121
- ? JSON.stringify(transformOriginDrag.translateDefault)
122
- : null;
123
117
  let last = null;
124
118
  let currentPointerX = event.clientX;
125
119
  let currentPointerY = event.clientY;
@@ -182,11 +176,29 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
182
176
  })
183
177
  : remotion_1.Internals.makeStaticDragOverride(origin));
184
178
  setDragOverrides(transformOriginDrag.nodePath, selected_outline_types_1.translateFieldKey, transformOriginDrag.translatePropStatus.status === 'keyframed'
185
- ? remotion_1.Internals.makeKeyframedDragOverride({
186
- status: transformOriginDrag.translatePropStatus,
187
- frame: transformOriginDrag.sourceFrame,
188
- value: translate,
189
- })
179
+ ? transformOriginDrag.originPropStatus.status === 'keyframed'
180
+ ? remotion_1.Internals.makeKeyframedDragOverride({
181
+ status: transformOriginDrag.translatePropStatus,
182
+ frame: transformOriginDrag.sourceFrame,
183
+ value: translate,
184
+ })
185
+ : {
186
+ type: 'keyframed',
187
+ status: {
188
+ ...transformOriginDrag.translatePropStatus,
189
+ keyframes: transformOriginDrag.translatePropStatus.keyframes.map((keyframe) => {
190
+ const keyframeTranslate = (0, timeline_translate_utils_1.parseTranslate)(String(keyframe.value));
191
+ return {
192
+ ...keyframe,
193
+ value: (0, timeline_translate_utils_1.serializeTranslate)(keyframeTranslate[0] +
194
+ nextTranslateX -
195
+ startTranslate[0], keyframeTranslate[1] +
196
+ nextTranslateY -
197
+ startTranslate[1]),
198
+ };
199
+ }),
200
+ },
201
+ }
190
202
  : remotion_1.Internals.makeStaticDragOverride(translate));
191
203
  };
192
204
  updateFromPointerPosition();
@@ -220,65 +232,27 @@ const SelectedOutlineTransformOriginHandle = ({ outline, onDraggingChange, targe
220
232
  clearDragOverrides(transformOriginDrag.nodePath);
221
233
  return;
222
234
  }
223
- const originChanged = last.origin !== transformOriginDrag.originValue;
224
- const translateChanged = last.translate !== transformOriginDrag.translateValue;
225
- if (!originChanged && !translateChanged) {
235
+ const { staticChanges, keyframedChanges } = (0, selected_outline_drag_1.getSelectedOutlineTransformOriginDragChanges)({
236
+ target: transformOriginDrag,
237
+ startTranslate,
238
+ origin: last.origin,
239
+ translate: last.translate,
240
+ });
241
+ if (staticChanges.length === 0 && keyframedChanges.length === 0) {
226
242
  clearDragOverrides(transformOriginDrag.nodePath);
227
243
  return;
228
244
  }
229
- const shouldSaveAsKeyframes = transformOriginDrag.originPropStatus.status === 'keyframed' ||
230
- transformOriginDrag.translatePropStatus.status === 'keyframed';
231
- const promise = shouldSaveAsKeyframes
245
+ const promise = staticChanges.length === 0
232
246
  ? (0, call_add_keyframe_1.callAddKeyframes)({
233
- sequenceKeyframes: [
234
- originChanged
235
- ? {
236
- fileName: transformOriginDrag.nodePath.absolutePath,
237
- nodePath: transformOriginDrag.nodePath,
238
- fieldKey: selected_outline_types_1.transformOriginFieldKey,
239
- sourceFrame: transformOriginDrag.sourceFrame,
240
- value: last.origin,
241
- schema: transformOriginDrag.schema,
242
- }
243
- : null,
244
- translateChanged
245
- ? {
246
- fileName: transformOriginDrag.nodePath.absolutePath,
247
- nodePath: transformOriginDrag.nodePath,
248
- fieldKey: selected_outline_types_1.translateFieldKey,
249
- sourceFrame: transformOriginDrag.sourceFrame,
250
- value: last.translate,
251
- schema: transformOriginDrag.schema,
252
- }
253
- : null,
254
- ].filter(no_react_1.NoReactInternals.truthy),
247
+ sequenceKeyframes: keyframedChanges,
255
248
  effectKeyframes: [],
256
249
  setPropStatuses,
257
250
  clientId: transformOriginDrag.clientId,
258
251
  })
259
252
  : (0, save_sequence_prop_1.saveSequenceProps)({
260
- changes: [
261
- originChanged
262
- ? {
263
- fileName: transformOriginDrag.nodePath.absolutePath,
264
- nodePath: transformOriginDrag.nodePath,
265
- fieldKey: selected_outline_types_1.transformOriginFieldKey,
266
- value: last.origin,
267
- defaultValue: defaultOrigin,
268
- schema: transformOriginDrag.schema,
269
- }
270
- : null,
271
- translateChanged
272
- ? {
273
- fileName: transformOriginDrag.nodePath.absolutePath,
274
- nodePath: transformOriginDrag.nodePath,
275
- fieldKey: selected_outline_types_1.translateFieldKey,
276
- value: last.translate,
277
- defaultValue: defaultTranslate,
278
- schema: transformOriginDrag.schema,
279
- }
280
- : null,
281
- ].filter(no_react_1.NoReactInternals.truthy),
253
+ changes: staticChanges,
254
+ addedKeyframes: keyframedChanges,
255
+ movedKeyframes: null,
282
256
  setPropStatuses,
283
257
  clientId: transformOriginDrag.clientId,
284
258
  undoLabel: 'Move transform origin',
@@ -478,6 +452,8 @@ const SelectedOutlinePolygon = ({ allDragTargets, allDragOutlines, contextMenuVa
478
452
  staticChanges.length > 0
479
453
  ? (0, save_sequence_prop_1.saveSequenceProps)({
480
454
  changes: staticChanges,
455
+ addedKeyframes: null,
456
+ movedKeyframes: null,
481
457
  setPropStatuses,
482
458
  clientId: drag.clientId,
483
459
  undoLabel: changes.length > 1
@@ -488,16 +464,12 @@ const SelectedOutlinePolygon = ({ allDragTargets, allDragOutlines, contextMenuVa
488
464
  : 'Move sequence back',
489
465
  })
490
466
  : Promise.resolve(),
491
- ...keyframedChanges.map((change) => (0, call_add_keyframe_1.callAddSequenceKeyframe)({
492
- fileName: change.fileName,
493
- nodePath: change.nodePath,
494
- fieldKey: change.fieldKey,
495
- sourceFrame: change.sourceFrame,
496
- value: change.value,
497
- schema: change.schema,
467
+ (0, call_add_keyframe_1.callAddKeyframes)({
468
+ sequenceKeyframes: keyframedChanges,
469
+ effectKeyframes: [],
498
470
  setPropStatuses,
499
- clientId: change.clientId,
500
- })),
471
+ clientId: drag.clientId,
472
+ }),
501
473
  ])
502
474
  .catch((err) => {
503
475
  (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
@@ -692,6 +664,8 @@ const SelectedOutlineScaleEdgeLine = ({ allScaleDragTargets, contextMenuValues,
692
664
  staticChanges.length > 0
693
665
  ? (0, save_sequence_prop_1.saveSequenceProps)({
694
666
  changes: staticChanges,
667
+ addedKeyframes: null,
668
+ movedKeyframes: null,
695
669
  setPropStatuses,
696
670
  clientId: scaleDrag.clientId,
697
671
  undoLabel: changes.length > 1
@@ -702,16 +676,12 @@ const SelectedOutlineScaleEdgeLine = ({ allScaleDragTargets, contextMenuValues,
702
676
  : 'Scale sequence back',
703
677
  })
704
678
  : Promise.resolve(),
705
- ...keyframedChanges.map((change) => (0, call_add_keyframe_1.callAddSequenceKeyframe)({
706
- fileName: change.fileName,
707
- nodePath: change.nodePath,
708
- fieldKey: change.fieldKey,
709
- sourceFrame: change.sourceFrame,
710
- value: change.value,
711
- schema: change.schema,
679
+ (0, call_add_keyframe_1.callAddKeyframes)({
680
+ sequenceKeyframes: keyframedChanges,
681
+ effectKeyframes: [],
712
682
  setPropStatuses,
713
- clientId: change.clientId,
714
- })),
683
+ clientId: scaleDrag.clientId,
684
+ }),
715
685
  ])
716
686
  .catch((err) => {
717
687
  (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
@@ -911,6 +881,8 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
911
881
  staticChanges.length > 0
912
882
  ? (0, save_sequence_prop_1.saveSequenceProps)({
913
883
  changes: staticChanges,
884
+ addedKeyframes: null,
885
+ movedKeyframes: null,
914
886
  setPropStatuses,
915
887
  clientId: rotationDrag.clientId,
916
888
  undoLabel: changes.length > 1
@@ -921,16 +893,12 @@ const SelectedOutlineRotationCornerHandle = ({ allRotationDragTargets, contextMe
921
893
  : 'Rotate sequence back',
922
894
  })
923
895
  : Promise.resolve(),
924
- ...keyframedChanges.map((change) => (0, call_add_keyframe_1.callAddSequenceKeyframe)({
925
- fileName: change.fileName,
926
- nodePath: change.nodePath,
927
- fieldKey: change.fieldKey,
928
- sourceFrame: change.sourceFrame,
929
- value: change.value,
930
- schema: change.schema,
896
+ (0, call_add_keyframe_1.callAddKeyframes)({
897
+ sequenceKeyframes: keyframedChanges,
898
+ effectKeyframes: [],
931
899
  setPropStatuses,
932
- clientId: change.clientId,
933
- })),
900
+ clientId: rotationDrag.clientId,
901
+ }),
934
902
  ])
935
903
  .catch((err) => {
936
904
  (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { type SelectedOutline } from './selected-outline-geometry';
3
3
  import { type SelectedOutlineTarget } from './selected-outline-types';
4
- export { applySelectedOutlineDragAxisLock, applySelectedOutlineTransformOriginAxisLock, compensateTranslateForTransformOrigin, getSelectedOutlineActiveSchema, getSelectedOutlineDragChanges, getSelectedOutlineDragValues, getSelectedOutlineKeyboardNudgeDelta, getSelectedOutlineKeyboardNudgeDeltas, getSelectedOutlineRotationDragChanges, getSelectedOutlineRotationDragStates, getSelectedOutlineRotationDragValues, getSelectedOutlineScaleDragChanges, getSelectedOutlineScaleDragStates, getSelectedOutlineScaleDragValues, getSelectedOutlineScaleEdgeInfo, getSelectedOutlineTransformOriginLockedAxis, isSelectedOutlineDragPastThreshold, selectedOutlineTransformOriginSnapThresholdPx, selectedOutlineUvSnapThresholdPx, snapSelectedOutlineRotationDeltaDegrees, snapSelectedOutlineTransformOriginUv, snapSelectedOutlineUv, } from './selected-outline-drag';
4
+ export { applySelectedOutlineDragAxisLock, applySelectedOutlineTransformOriginAxisLock, compensateTranslateForTransformOrigin, getSelectedOutlineActiveSchema, getSelectedOutlineDragChanges, getSelectedOutlineDragValues, getSelectedOutlineKeyboardNudgeDelta, getSelectedOutlineKeyboardNudgeDeltas, getSelectedOutlineRotationDragChanges, getSelectedOutlineRotationDragStates, getSelectedOutlineRotationDragValues, getSelectedOutlineScaleDragChanges, getSelectedOutlineScaleDragStates, getSelectedOutlineScaleDragValues, getSelectedOutlineScaleEdgeInfo, getSelectedOutlineTransformOriginDragChanges, getSelectedOutlineTransformOriginLockedAxis, isSelectedOutlineDragPastThreshold, selectedOutlineTransformOriginSnapThresholdPx, selectedOutlineUvSnapThresholdPx, snapSelectedOutlineRotationDeltaDegrees, snapSelectedOutlineTransformOriginUv, snapSelectedOutlineUv, } from './selected-outline-drag';
5
5
  export { getOutlineSelectionInteraction, getSelectedEffectFieldsBySequenceKey, getSelectedOutlineRotationCornerInfo, getSelectedOutlineRotationDeltaDegrees, getSelectedOutlineRotationPivot, getSelectedSequenceKeys, getSequencesWithSelectableOutlines, getTransformedSvgViewportPoints, } from './selected-outline-measurement';
6
6
  export { selectedOutlineDragThresholdPx } from './selected-outline-types';
7
7
  export type { SelectedOutlineDragState, SelectedOutlineRotationDragState, SelectedOutlineScaleDragState, } from './selected-outline-types';
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.SelectedOutlineOverlay = exports.orderOutlinesForRendering = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineActiveSchema = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = void 0;
36
+ exports.SelectedOutlineOverlay = exports.orderOutlinesForRendering = exports.selectedOutlineDragThresholdPx = exports.getTransformedSvgViewportPoints = exports.getSequencesWithSelectableOutlines = exports.getSelectedSequenceKeys = exports.getSelectedOutlineRotationPivot = exports.getSelectedOutlineRotationDeltaDegrees = exports.getSelectedOutlineRotationCornerInfo = exports.getSelectedEffectFieldsBySequenceKey = exports.getOutlineSelectionInteraction = exports.snapSelectedOutlineUv = exports.snapSelectedOutlineTransformOriginUv = exports.snapSelectedOutlineRotationDeltaDegrees = exports.selectedOutlineUvSnapThresholdPx = exports.selectedOutlineTransformOriginSnapThresholdPx = exports.isSelectedOutlineDragPastThreshold = exports.getSelectedOutlineTransformOriginLockedAxis = exports.getSelectedOutlineTransformOriginDragChanges = exports.getSelectedOutlineScaleEdgeInfo = exports.getSelectedOutlineScaleDragValues = exports.getSelectedOutlineScaleDragStates = exports.getSelectedOutlineScaleDragChanges = exports.getSelectedOutlineRotationDragValues = exports.getSelectedOutlineRotationDragStates = exports.getSelectedOutlineRotationDragChanges = exports.getSelectedOutlineKeyboardNudgeDeltas = exports.getSelectedOutlineKeyboardNudgeDelta = exports.getSelectedOutlineDragValues = exports.getSelectedOutlineDragChanges = exports.getSelectedOutlineActiveSchema = exports.compensateTranslateForTransformOrigin = exports.applySelectedOutlineTransformOriginAxisLock = exports.applySelectedOutlineDragAxisLock = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const player_1 = require("@remotion/player");
39
39
  const react_1 = __importStar(require("react"));
@@ -74,6 +74,7 @@ Object.defineProperty(exports, "getSelectedOutlineScaleDragChanges", { enumerabl
74
74
  Object.defineProperty(exports, "getSelectedOutlineScaleDragStates", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleDragStates; } });
75
75
  Object.defineProperty(exports, "getSelectedOutlineScaleDragValues", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleDragValues; } });
76
76
  Object.defineProperty(exports, "getSelectedOutlineScaleEdgeInfo", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineScaleEdgeInfo; } });
77
+ Object.defineProperty(exports, "getSelectedOutlineTransformOriginDragChanges", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineTransformOriginDragChanges; } });
77
78
  Object.defineProperty(exports, "getSelectedOutlineTransformOriginLockedAxis", { enumerable: true, get: function () { return selected_outline_drag_2.getSelectedOutlineTransformOriginLockedAxis; } });
78
79
  Object.defineProperty(exports, "isSelectedOutlineDragPastThreshold", { enumerable: true, get: function () { return selected_outline_drag_2.isSelectedOutlineDragPastThreshold; } });
79
80
  Object.defineProperty(exports, "selectedOutlineTransformOriginSnapThresholdPx", { enumerable: true, get: function () { return selected_outline_drag_2.selectedOutlineTransformOriginSnapThresholdPx; } });
@@ -707,6 +708,8 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
707
708
  staticChanges.length > 0
708
709
  ? (0, save_sequence_prop_1.saveSequenceProps)({
709
710
  changes: staticChanges,
711
+ addedKeyframes: null,
712
+ movedKeyframes: null,
710
713
  setPropStatuses,
711
714
  clientId: session.clientId,
712
715
  undoLabel: changes.length > 1 ? 'Move selected sequences' : 'Move sequence',
@@ -715,16 +718,12 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
715
718
  : 'Move sequence back',
716
719
  })
717
720
  : Promise.resolve(),
718
- ...keyframedChanges.map((change) => (0, call_add_keyframe_1.callAddSequenceKeyframe)({
719
- fileName: change.fileName,
720
- nodePath: change.nodePath,
721
- fieldKey: change.fieldKey,
722
- sourceFrame: change.sourceFrame,
723
- value: change.value,
724
- schema: change.schema,
721
+ (0, call_add_keyframe_1.callAddKeyframes)({
722
+ sequenceKeyframes: keyframedChanges,
723
+ effectKeyframes: [],
725
724
  setPropStatuses,
726
- clientId: change.clientId,
727
- })),
725
+ clientId: session.clientId,
726
+ }),
728
727
  ])
729
728
  .catch((err) => {
730
729
  (0, NotificationCenter_1.showNotification)(`Could not save sequence props: ${err instanceof Error ? err.message : String(err)}`, 4000);
@@ -56,6 +56,7 @@ const SequencePropsObserver_1 = require("./SequencePropsObserver");
56
56
  const should_show_track_in_timeline_1 = require("./should-show-track-in-timeline");
57
57
  const should_subscribe_to_sequence_props_1 = require("./should-subscribe-to-sequence-props");
58
58
  const SubscribeToNodePaths_1 = require("./SubscribeToNodePaths");
59
+ const timeline_asset_drop_context_1 = require("./timeline-asset-drop-context");
59
60
  const timeline_refs_1 = require("./timeline-refs");
60
61
  const TimelineDragHandler_1 = require("./TimelineDragHandler");
61
62
  const TimelineHeightContainer_1 = require("./TimelineHeightContainer");
@@ -72,6 +73,7 @@ const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
72
73
  const TimelineTracks_1 = require("./TimelineTracks");
73
74
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
74
75
  const use_resolved_stack_1 = require("./use-resolved-stack");
76
+ const use_timeline_asset_drop_1 = require("./use-timeline-asset-drop");
75
77
  const container = {
76
78
  minHeight: '100%',
77
79
  flex: 1,
@@ -83,6 +85,7 @@ const container = {
83
85
  const noop = () => undefined;
84
86
  const TimelineContextMenuArea = ({ children }) => {
85
87
  var _a, _b;
88
+ const assetDropFrame = (0, use_timeline_asset_drop_1.useTimelineAssetDrop)();
86
89
  const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
87
90
  const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
88
91
  const [isAddingSolid, setIsAddingSolid] = (0, react_1.useState)(false);
@@ -128,6 +131,7 @@ const TimelineContextMenuArea = ({ children }) => {
128
131
  const result = await (0, call_api_1.callApi)('/api/insert-jsx-element', {
129
132
  compositionFile,
130
133
  compositionId: currentCompositionId,
134
+ from: null,
131
135
  element: {
132
136
  type: 'solid',
133
137
  width: videoConfig.width,
@@ -151,7 +155,8 @@ const TimelineContextMenuArea = ({ children }) => {
151
155
  const insertAsset = (0, react_1.useCallback)(async () => {
152
156
  if (!canInsertAsset ||
153
157
  currentCompositionId === null ||
154
- compositionFile === null) {
158
+ compositionFile === null ||
159
+ videoConfig === null) {
155
160
  return;
156
161
  }
157
162
  const files = await (0, import_assets_1.pickFilesToImport)();
@@ -162,17 +167,19 @@ const TimelineContextMenuArea = ({ children }) => {
162
167
  try {
163
168
  await (0, import_assets_1.importAssets)({
164
169
  files,
170
+ fps: videoConfig.fps,
165
171
  compositionFile,
166
172
  compositionId: currentCompositionId,
167
173
  destinationDimensions: null,
168
174
  dropPosition: null,
175
+ from: null,
169
176
  svgImportMode: 'image',
170
177
  });
171
178
  }
172
179
  finally {
173
180
  setIsAddingAsset(false);
174
181
  }
175
- }, [canInsertAsset, compositionFile, currentCompositionId]);
182
+ }, [canInsertAsset, compositionFile, currentCompositionId, videoConfig]);
176
183
  const contextMenuItems = (0, react_1.useMemo)(() => {
177
184
  return [
178
185
  {
@@ -201,7 +208,7 @@ const TimelineContextMenuArea = ({ children }) => {
201
208
  },
202
209
  ];
203
210
  }, [insertSolid, canInsertSolid, insertAsset, canInsertAsset]);
204
- return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { ref: timeline_refs_1.timelineVerticalScroll, values: contextMenuItems, onOpen: null, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: children }));
211
+ return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { ref: timeline_refs_1.timelineVerticalScroll, values: contextMenuItems, onOpen: null, style: container, className: 'css-reset ' + is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(timeline_asset_drop_context_1.TimelineAssetDropFrameContext.Provider, { value: assetDropFrame, children: children }) }));
205
212
  };
206
213
  const TimelineInner = () => {
207
214
  var _a;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const TimelineAssetDropIndicator: React.FC;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineAssetDropIndicator = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const remotion_1 = require("remotion");
7
+ const colors_1 = require("../../helpers/colors");
8
+ const get_left_of_timeline_slider_1 = require("../../helpers/get-left-of-timeline-slider");
9
+ const timeline_asset_drop_context_1 = require("./timeline-asset-drop-context");
10
+ const timeline_refs_1 = require("./timeline-refs");
11
+ const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
12
+ const indicator = {
13
+ backgroundColor: colors_1.RULER_COLOR,
14
+ bottom: 0,
15
+ pointerEvents: 'none',
16
+ position: 'absolute',
17
+ top: 0,
18
+ width: 1,
19
+ zIndex: 10,
20
+ };
21
+ const TimelineAssetDropIndicator = () => {
22
+ var _a;
23
+ var _b;
24
+ const frame = (0, react_1.useContext)(timeline_asset_drop_context_1.TimelineAssetDropFrameContext);
25
+ const timelineWidth = (0, react_1.useContext)(TimelineWidthProvider_1.TimelineWidthContext);
26
+ const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
27
+ if (frame === null || timelineWidth === null || videoConfig === null) {
28
+ return null;
29
+ }
30
+ const width = (_b = (_a = timeline_refs_1.sliderAreaRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : timelineWidth;
31
+ const left = (0, get_left_of_timeline_slider_1.getXPositionOfItemInTimelineImperatively)(frame, videoConfig.durationInFrames, width);
32
+ return (jsx_runtime_1.jsx("div", { "data-timeline-asset-drop-indicator": "true", style: {
33
+ ...indicator,
34
+ transform: `translateX(${left - 0.5}px)`,
35
+ } }));
36
+ };
37
+ exports.TimelineAssetDropIndicator = TimelineAssetDropIndicator;
@@ -710,13 +710,7 @@ const TimelineClipboardKeybindings = () => {
710
710
  (0, NotificationCenter_1.showNotification)('Cannot paste onto an easing that cannot be updated', 3000);
711
711
  return;
712
712
  }
713
- return updatePromise
714
- .then(() => {
715
- (0, NotificationCenter_1.showNotification)(easingSelections.length === 1
716
- ? 'Pasted easing'
717
- : 'Pasted easing to selected segments', 2000);
718
- })
719
- .catch((err) => {
713
+ return updatePromise.catch((err) => {
720
714
  (0, NotificationCenter_1.showNotification)(`Could not paste easing: ${err.message}`, 3000);
721
715
  });
722
716
  }
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
7
7
  const is_menu_item_1 = require("../Menu/is-menu-item");
8
8
  const timeline_refs_1 = require("./timeline-refs");
9
+ const TimelineAssetDropIndicator_1 = require("./TimelineAssetDropIndicator");
9
10
  const TimelineSelection_1 = require("./TimelineSelection");
10
11
  const outer = {
11
12
  width: '100%',
@@ -31,8 +32,8 @@ const TimelineScrollable = ({ children }) => {
31
32
  minHeight: '100%',
32
33
  };
33
34
  }, []);
34
- return (jsx_runtime_1.jsxs("div", { ref: timeline_refs_1.scrollableRef, style: outer, className: is_menu_item_1.HORIZONTAL_SCROLLBAR_CLASSNAME, onPointerDownCapture: onPointerDownCapture, children: [
35
- jsx_runtime_1.jsx("div", { style: containerStyle, children: children }), marqueeRect === null ? null : (jsx_runtime_1.jsx("div", { style: {
35
+ return (jsx_runtime_1.jsxs("div", { ref: timeline_refs_1.scrollableRef, "data-timeline-scrollable": "true", style: outer, className: is_menu_item_1.HORIZONTAL_SCROLLBAR_CLASSNAME, onPointerDownCapture: onPointerDownCapture, children: [
36
+ jsx_runtime_1.jsx("div", { style: containerStyle, children: children }), jsx_runtime_1.jsx(TimelineAssetDropIndicator_1.TimelineAssetDropIndicator, {}), marqueeRect === null ? null : (jsx_runtime_1.jsx("div", { style: {
36
37
  ...marqueeStyle,
37
38
  height: marqueeRect.bottom - marqueeRect.top,
38
39
  left: marqueeRect.left,
@@ -117,6 +117,10 @@ export declare const getTimelineMarqueeSelection: ({ candidates, lockedSelection
117
117
  readonly lockedSelectionKind: TimelineMarqueeSelectionKind | null;
118
118
  readonly selectedItems: readonly TimelineSelection[];
119
119
  };
120
+ export declare const extendTimelineMarqueeSelection: ({ currentSelection, marqueeSelection, }: {
121
+ readonly currentSelection: readonly TimelineSelection[];
122
+ readonly marqueeSelection: readonly TimelineSelection[];
123
+ }) => readonly TimelineSelection[];
120
124
  type TimelineSelectionContextValue = {
121
125
  readonly canSelect: boolean;
122
126
  readonly selectedItems: readonly TimelineSelection[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useTimelineRowHighlightBackground = exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineFocusableItem = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineItems = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.TimelineSelectionOrderProvider = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineRowHighlightBackground = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
3
+ exports.useTimelineRowHighlightBackground = exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineFocusableItem = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineItems = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.TimelineSelectionOrderProvider = exports.extendTimelineMarqueeSelection = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineRowHighlightBackground = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
4
4
  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");
@@ -265,6 +265,28 @@ const getTimelineMarqueeSelection = ({ candidates, lockedSelectionKind, marqueeR
265
265
  };
266
266
  };
267
267
  exports.getTimelineMarqueeSelection = getTimelineMarqueeSelection;
268
+ const extendTimelineMarqueeSelection = ({ currentSelection, marqueeSelection, }) => {
269
+ if (marqueeSelection.length === 0) {
270
+ return currentSelection;
271
+ }
272
+ const marqueeKind = getTimelineMarqueeSelectionKind(marqueeSelection[0]);
273
+ if (marqueeKind === null) {
274
+ return marqueeSelection;
275
+ }
276
+ const selectedKeys = new Set(currentSelection.map((item) => (0, exports.getTimelineSelectionKey)(item)));
277
+ return [
278
+ ...currentSelection.filter((item) => isTimelineSelectionCompatibleWithMarqueeKind(item, marqueeKind)),
279
+ ...marqueeSelection.filter((item) => {
280
+ const key = (0, exports.getTimelineSelectionKey)(item);
281
+ if (selectedKeys.has(key)) {
282
+ return false;
283
+ }
284
+ selectedKeys.add(key);
285
+ return true;
286
+ }),
287
+ ];
288
+ };
289
+ exports.extendTimelineMarqueeSelection = extendTimelineMarqueeSelection;
268
290
  const defaultTimelineSelectionContextValue = {
269
291
  canSelect: false,
270
292
  selectedItems: [],
@@ -864,7 +886,7 @@ const useCurrentTimelineSelectionStateAsRef = () => {
864
886
  };
865
887
  exports.useCurrentTimelineSelectionStateAsRef = useCurrentTimelineSelectionStateAsRef;
866
888
  const useTimelineMarqueeSelection = () => {
867
- const { canSelect, getMarqueeSelection, selectItems } = (0, exports.useTimelineSelection)();
889
+ const { canSelect, getMarqueeSelection, selectedItems, selectItems } = (0, exports.useTimelineSelection)();
868
890
  const { isHighestContext } = (0, z_index_1.useZIndex)();
869
891
  const [marqueeRect, setMarqueeRect] = (0, react_1.useState)(null);
870
892
  const onPointerDownCapture = (0, react_1.useCallback)((event) => {
@@ -874,7 +896,7 @@ const useTimelineMarqueeSelection = () => {
874
896
  if (event.button !== 0 || !canSelect) {
875
897
  return;
876
898
  }
877
- if (event.shiftKey || event.metaKey || event.ctrlKey) {
899
+ if (event.shiftKey) {
878
900
  return;
879
901
  }
880
902
  if (!(event.target instanceof Element)) {
@@ -908,6 +930,8 @@ const useTimelineMarqueeSelection = () => {
908
930
  document.body.style.webkitUserSelect = 'none';
909
931
  let hasDragged = false;
910
932
  let lockedSelectionKind = null;
933
+ const extendSelection = event.metaKey || event.ctrlKey;
934
+ const selectionBeforeMarquee = selectedItems;
911
935
  const cleanup = () => {
912
936
  var _a;
913
937
  window.removeEventListener('pointermove', onPointerMove);
@@ -941,7 +965,12 @@ const useTimelineMarqueeSelection = () => {
941
965
  const nextSelection = getMarqueeSelection(rect, lockedSelectionKind);
942
966
  lockedSelectionKind = nextSelection.lockedSelectionKind;
943
967
  setMarqueeRect(rect);
944
- selectItems(nextSelection.selectedItems);
968
+ selectItems(extendSelection
969
+ ? (0, exports.extendTimelineMarqueeSelection)({
970
+ currentSelection: selectionBeforeMarquee,
971
+ marqueeSelection: nextSelection.selectedItems,
972
+ })
973
+ : nextSelection.selectedItems);
945
974
  };
946
975
  const onPointerMove = (moveEvent) => {
947
976
  updateSelection(moveEvent.clientX, moveEvent.clientY);
@@ -956,7 +985,13 @@ const useTimelineMarqueeSelection = () => {
956
985
  window.addEventListener('pointermove', onPointerMove);
957
986
  window.addEventListener('pointerup', onPointerUp);
958
987
  window.addEventListener('pointercancel', onPointerCancel);
959
- }, [canSelect, getMarqueeSelection, isHighestContext, selectItems]);
988
+ }, [
989
+ canSelect,
990
+ getMarqueeSelection,
991
+ isHighestContext,
992
+ selectedItems,
993
+ selectItems,
994
+ ]);
960
995
  return { marqueeRect, onPointerDownCapture };
961
996
  };
962
997
  exports.useTimelineMarqueeSelection = useTimelineMarqueeSelection;