@remotion/studio 4.0.486 → 4.0.488

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 (67) hide show
  1. package/dist/components/Canvas.js +156 -4
  2. package/dist/components/ContextMenu.js +2 -1
  3. package/dist/components/CurrentComposition.js +43 -2
  4. package/dist/components/EditorContexts.js +2 -1
  5. package/dist/components/GlobalKeybindings.js +19 -0
  6. package/dist/components/InspectorPanel/DefaultInspector.js +2 -1
  7. package/dist/components/InspectorSourceLocation.d.ts +1 -0
  8. package/dist/components/InspectorSourceLocation.js +18 -3
  9. package/dist/components/KeyboardShortcutsExplainer.js +4 -0
  10. package/dist/components/Preview.js +1 -1
  11. package/dist/components/PreviewToolbar.js +2 -1
  12. package/dist/components/RenderButton.js +1 -0
  13. package/dist/components/RenderModal/OptionExplainer.d.ts +11 -1
  14. package/dist/components/RenderModal/OptionExplainer.js +31 -11
  15. package/dist/components/RenderModal/OptionExplainerBubble.d.ts +15 -1
  16. package/dist/components/RenderModal/OptionExplainerBubble.js +17 -3
  17. package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +1 -0
  18. package/dist/components/RenderModal/SchemaEditor/Fieldset.js +6 -1
  19. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +1 -2
  20. package/dist/components/RenderModal/WebRenderModal.js +5 -2
  21. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +3 -0
  22. package/dist/components/RenderModal/WebRenderModalAdvanced.js +92 -5
  23. package/dist/components/RenderModal/WebRenderModalBasic.js +2 -2
  24. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -0
  25. package/dist/components/RenderQueue/client-side-render-types.d.ts +2 -1
  26. package/dist/components/SelectedOutlineElement.d.ts +4 -0
  27. package/dist/components/SelectedOutlineElement.js +56 -11
  28. package/dist/components/SelectedOutlineOverlay.d.ts +2 -0
  29. package/dist/components/SelectedOutlineOverlay.js +55 -3
  30. package/dist/components/SelectedOutlineUvControls.js +13 -6
  31. package/dist/components/SnappingProvider.d.ts +4 -0
  32. package/dist/components/SnappingProvider.js +24 -0
  33. package/dist/components/SnappingToggle.d.ts +2 -0
  34. package/dist/components/SnappingToggle.js +26 -0
  35. package/dist/components/Splitter/SplitterContext.d.ts +1 -1
  36. package/dist/components/Timeline/Timeline.js +8 -6
  37. package/dist/components/Timeline/TimelineDragHandler.js +2 -1
  38. package/dist/components/Timeline/TimelineSelection.js +8 -1
  39. package/dist/components/Timeline/TimelineSequence.js +15 -8
  40. package/dist/components/Timeline/TimelineSequenceItem.js +63 -51
  41. package/dist/components/VisualControls/ClickableFileName.js +2 -2
  42. package/dist/components/VisualControls/VisualControlsContent.js +9 -1
  43. package/dist/components/effect-drag-and-drop.js +30 -9
  44. package/dist/components/import-assets.d.ts +1 -1
  45. package/dist/components/options-sidebar-tabs.d.ts +1 -0
  46. package/dist/components/options-sidebar-tabs.js +6 -1
  47. package/dist/components/selected-outline-snap.d.ts +36 -0
  48. package/dist/components/selected-outline-snap.js +158 -0
  49. package/dist/esm/{chunk-975rp13y.js → chunk-nn36hyt1.js} +5001 -3970
  50. package/dist/esm/index.mjs +3 -0
  51. package/dist/esm/internals.mjs +5001 -3970
  52. package/dist/esm/previewEntry.mjs +5544 -4513
  53. package/dist/esm/renderEntry.mjs +1 -1
  54. package/dist/helpers/interactivity-enabled.d.ts +1 -0
  55. package/dist/helpers/interactivity-enabled.js +7 -0
  56. package/dist/helpers/retry-payload.js +1 -0
  57. package/dist/helpers/use-menu-structure.js +43 -2
  58. package/dist/icons/magnet.d.ts +3 -0
  59. package/dist/icons/magnet.js +8 -0
  60. package/dist/icons/react.d.ts +5 -0
  61. package/dist/icons/react.js +8 -0
  62. package/dist/state/editor-guides.d.ts +2 -2
  63. package/dist/state/editor-snapping.d.ts +8 -0
  64. package/dist/state/editor-snapping.js +18 -0
  65. package/dist/state/modals.d.ts +2 -1
  66. package/dist/visual-controls/VisualControls.js +4 -0
  67. package/package.json +12 -12
@@ -40,12 +40,15 @@ const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
41
  const no_react_1 = require("remotion/no-react");
42
42
  const client_id_1 = require("../helpers/client-id");
43
+ const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
43
44
  const use_keybinding_1 = require("../helpers/use-keybinding");
45
+ const editor_guides_1 = require("../state/editor-guides");
44
46
  const editor_outlines_1 = require("../state/editor-outlines");
45
47
  const scale_lock_1 = require("../state/scale-lock");
46
48
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
47
49
  const selected_outline_drag_1 = require("./selected-outline-drag");
48
50
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
51
+ const selected_outline_snap_1 = require("./selected-outline-snap");
49
52
  const selected_outline_types_1 = require("./selected-outline-types");
50
53
  const selected_outline_uv_1 = require("./selected-outline-uv");
51
54
  const SelectedOutlineElement_1 = require("./SelectedOutlineElement");
@@ -95,6 +98,19 @@ const outlineContainer = {
95
98
  pointerEvents: 'none',
96
99
  overflow: 'visible',
97
100
  };
101
+ const SelectedOutlineSnapIndicators = ({ activeSnapPoints, compositionHeight, compositionWidth, scale }) => {
102
+ if (activeSnapPoints.length === 0) {
103
+ return null;
104
+ }
105
+ return (jsx_runtime_1.jsx("g", { pointerEvents: "none", children: activeSnapPoints.map((snapPoint) => {
106
+ if (snapPoint.target.axis === 'x') {
107
+ const x = snapPoint.target.position * scale;
108
+ return (jsx_runtime_1.jsx("line", { x1: x, x2: x, y1: 0, y2: compositionHeight * scale, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
109
+ }
110
+ const y = snapPoint.target.position * scale;
111
+ return (jsx_runtime_1.jsx("line", { x1: 0, x2: compositionWidth * scale, y1: y, y2: y, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
112
+ }) }));
113
+ };
98
114
  const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
99
115
  return [...outlines].sort((a, b) => {
100
116
  var _a, _b;
@@ -105,9 +121,10 @@ const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
105
121
  });
106
122
  };
107
123
  exports.orderOutlinesForRendering = orderOutlinesForRendering;
108
- const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
124
+ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, translationX, translationY, }) => {
109
125
  const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
110
126
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
127
+ const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
111
128
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
112
129
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
113
130
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
@@ -115,12 +132,14 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
115
132
  const { setPropStatuses, setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
116
133
  const { getScaleLockState } = (0, react_1.useContext)(scale_lock_1.ScaleLockContext);
117
134
  const { editorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
135
+ const { editorShowGuides, guidesList } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
118
136
  const { frameBack, frameForward, getCurrentFrame, seek } = player_1.PlayerInternals.usePlayer();
119
137
  const keybindings = (0, use_keybinding_1.useKeybinding)();
120
138
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
121
139
  const [outlines, setOutlines] = (0, react_1.useState)([]);
122
140
  const [hoveredOutlineKey, setHoveredOutlineKey] = (0, react_1.useState)(null);
123
141
  const [draggingOutline, setDraggingOutline] = (0, react_1.useState)(false);
142
+ const [activeSnapPoints, setActiveSnapPoints] = (0, react_1.useState)([]);
124
143
  const overlayRef = (0, react_1.useRef)(null);
125
144
  const keyboardNudgeSessionRef = (0, react_1.useRef)(null);
126
145
  const saveKeyboardNudgeSessionRef = (0, react_1.useRef)(() => undefined);
@@ -129,12 +148,18 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
129
148
  if (dragging) {
130
149
  setHoveredOutlineKey(null);
131
150
  }
151
+ else {
152
+ setActiveSnapPoints([]);
153
+ }
154
+ }, []);
155
+ const onSnapPointsChange = (0, react_1.useCallback)((snapPoints) => {
156
+ setActiveSnapPoints(snapPoints);
132
157
  }, []);
133
158
  const selectOutlineItem = (0, react_1.useCallback)((item, interaction) => {
134
159
  selectItem(item, interaction, undefined, { reveal: true });
135
160
  }, [selectItem]);
136
161
  const outlineTargets = (0, react_1.useMemo)(() => {
137
- if (!editorShowOutlines) {
162
+ if (!interactivity_enabled_1.studioInteractivityEnabled || !editorShowOutlines) {
138
163
  return [];
139
164
  }
140
165
  const selectedSequenceKeys = (0, selected_outline_measurement_1.getSelectedSequenceKeys)(selectedItems);
@@ -391,11 +416,24 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
391
416
  const outlinesForRendering = (0, react_1.useMemo)(() => {
392
417
  return (0, exports.orderOutlinesForRendering)({ outlines, targetsByKey });
393
418
  }, [outlines, targetsByKey]);
419
+ const outlinesByKey = (0, react_1.useMemo)(() => {
420
+ return new Map(outlines.map((outline) => [outline.key, outline]));
421
+ }, [outlines]);
394
422
  const allDragTargets = (0, react_1.useMemo)(() => {
395
423
  return outlineTargets.flatMap((target) => (target.selected || target.containsSelection) && target.drag !== null
396
424
  ? [target.drag]
397
425
  : []);
398
426
  }, [outlineTargets]);
427
+ const allDragOutlines = (0, react_1.useMemo)(() => {
428
+ return outlineTargets.flatMap((target) => {
429
+ if ((!target.selected && !target.containsSelection) ||
430
+ target.drag === null) {
431
+ return [];
432
+ }
433
+ const outline = outlinesByKey.get(target.key);
434
+ return outline === undefined ? [] : [outline];
435
+ });
436
+ }, [outlineTargets, outlinesByKey]);
399
437
  const allScaleDragTargets = (0, react_1.useMemo)(() => {
400
438
  return outlineTargets.flatMap((target) => target.selected && target.scaleDrag !== null ? [target.scaleDrag] : []);
401
439
  }, [outlineTargets]);
@@ -404,6 +442,19 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
404
442
  ? [target.rotationDrag]
405
443
  : []);
406
444
  }, [outlineTargets]);
445
+ const guidesForSnap = (0, react_1.useMemo)(() => {
446
+ if (!editorShowGuides || (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition') {
447
+ return [];
448
+ }
449
+ return guidesList.filter((guide) => guide.compositionId === canvasContent.compositionId);
450
+ }, [canvasContent, editorShowGuides, guidesList]);
451
+ const snapTargets = (0, react_1.useMemo)(() => {
452
+ return (0, selected_outline_snap_1.getSelectedOutlineSnapTargets)({
453
+ compositionHeight,
454
+ compositionWidth,
455
+ guides: guidesForSnap,
456
+ });
457
+ }, [compositionHeight, compositionWidth, guidesForSnap]);
407
458
  const saveKeyboardNudgeSession = (0, react_1.useCallback)(() => {
408
459
  const session = keyboardNudgeSessionRef.current;
409
460
  if (session === null) {
@@ -671,6 +722,7 @@ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
671
722
  if (outlineTargets.length === 0) {
672
723
  return null;
673
724
  }
674
- return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineElement, { allDragTargets: allDragTargets, allRotationDragTargets: allRotationDragTargets, allScaleDragTargets: allScaleDragTargets, dragging: draggingOutline, hovered: hoveredOutlineKey === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: setHoveredOutlineKey, onSelect: selectOutlineItem, scale: scale, target: targetsByKey.get(outline.key) }, outline.key))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineTransformOriginHandle, { outline: outline, onDraggingChange: onDraggingChange, target: targetsByKey.get(outline.key) }, `${outline.key}-transform-origin`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleConnectionLayer, { outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-connection-lines`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleCircleLayer, { onDraggingChange: onDraggingChange, onSelect: selectOutlineItem, outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-handles`)))] }));
725
+ return (jsx_runtime_1.jsxs("svg", { ref: overlayRef, style: outlineContainer, width: "100%", height: "100%", "aria-hidden": "true", children: [
726
+ jsx_runtime_1.jsx(SelectedOutlineSnapIndicators, { activeSnapPoints: activeSnapPoints, compositionHeight: compositionHeight, compositionWidth: compositionWidth, scale: scale }), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineElement, { allDragTargets: allDragTargets, allDragOutlines: allDragOutlines, allRotationDragTargets: allRotationDragTargets, allScaleDragTargets: allScaleDragTargets, dragging: draggingOutline, hovered: hoveredOutlineKey === outline.key, outline: outline, onDraggingChange: onDraggingChange, onHoverChange: setHoveredOutlineKey, onSnapPointsChange: onSnapPointsChange, onSelect: selectOutlineItem, scale: scale, snapTargets: snapTargets, target: targetsByKey.get(outline.key) }, outline.key))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineElement_1.SelectedOutlineTransformOriginHandle, { outline: outline, onDraggingChange: onDraggingChange, target: targetsByKey.get(outline.key) }, `${outline.key}-transform-origin`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleConnectionLayer, { outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-connection-lines`))), outlinesForRendering.map((outline) => (jsx_runtime_1.jsx(SelectedOutlineUvControls_1.SelectedOutlineUvHandleCircleLayer, { onDraggingChange: onDraggingChange, onSelect: selectOutlineItem, outline: outline, target: targetsByKey.get(outline.key) }, `${outline.key}-uv-handles`)))] }));
675
727
  };
676
728
  exports.SelectedOutlineOverlay = SelectedOutlineOverlay;
@@ -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 editor_snapping_1 = require("../state/editor-snapping");
41
42
  const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
42
43
  const selected_outline_drag_1 = require("./selected-outline-drag");
43
44
  const selected_outline_measurement_1 = require("./selected-outline-measurement");
@@ -384,6 +385,7 @@ const trimLineToCircleEdges = ({ from, fromRadius, to, toRadius, }) => {
384
385
  };
385
386
  const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
386
387
  const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
388
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
387
389
  const { rotationControl } = control;
388
390
  const field = rotationControl === null || rotationControl === void 0 ? void 0 : rotationControl.field;
389
391
  const onPointerDown = react_1.default.useCallback((event) => {
@@ -413,7 +415,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
413
415
  let lastValue = null;
414
416
  const updateRotationDragOverride = () => {
415
417
  const rawValue = control.rotation + accumulatedDelta;
416
- const snappedValue = rotationLocked
418
+ const snappedValue = rotationLocked && editorSnapping
417
419
  ? snapRotationDegrees(rawValue)
418
420
  : rawValue;
419
421
  const nextValue = (0, selected_outline_uv_1.roundNumericUvEllipseValue)(snappedValue, field.fieldSchema);
@@ -497,6 +499,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
497
499
  }, [
498
500
  clearEffectDragOverrides,
499
501
  control,
502
+ editorSnapping,
500
503
  field,
501
504
  onDraggingChange,
502
505
  rotationControl,
@@ -522,6 +525,7 @@ const SelectedUvEllipseRotationHandle = ({ control, onDraggingChange }) => {
522
525
  };
523
526
  const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSelect, outline }) => {
524
527
  const { setEffectDragOverrides, clearEffectDragOverrides, setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
528
+ const { editorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
525
529
  const position = (0, react_1.useMemo)(() => (0, selected_outline_uv_1.getUvHandlePosition)(outline.points, handle.value), [handle.value, outline.points]);
526
530
  const onPointerDown = react_1.default.useCallback((event) => {
527
531
  if (event.button !== 0) {
@@ -556,11 +560,13 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
556
560
  rect: svgRect,
557
561
  });
558
562
  const rawUv = (0, selected_outline_uv_1.getUvCoordinateForPoint)(outline.points, point);
559
- const snappedUv = (0, selected_outline_drag_1.snapSelectedOutlineUv)({
560
- point,
561
- points: outline.points,
562
- uv: rawUv,
563
- });
563
+ const snappedUv = editorSnapping
564
+ ? (0, selected_outline_drag_1.snapSelectedOutlineUv)({
565
+ point,
566
+ points: outline.points,
567
+ uv: rawUv,
568
+ })
569
+ : rawUv;
564
570
  const nextValue = (0, selected_outline_uv_1.roundUvCoordinate)((0, selected_outline_uv_1.constrainUv)(snappedUv, handle.fieldSchema), handle.fieldSchema);
565
571
  lastValue = nextValue;
566
572
  setEffectDragOverrides(handle.nodePath, handle.effectIndex, handle.fieldKey, handle.propStatus.status === 'keyframed'
@@ -644,6 +650,7 @@ const SelectedUvHandleCircle = ({ handle, nodePathInfo, onDraggingChange, onSele
644
650
  window.addEventListener('pointercancel', onPointerUp);
645
651
  }, [
646
652
  clearEffectDragOverrides,
653
+ editorSnapping,
647
654
  handle,
648
655
  nodePathInfo,
649
656
  onDraggingChange,
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const SnappingProvider: React.FC<{
3
+ readonly children: React.ReactNode;
4
+ }>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnappingProvider = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const editor_snapping_1 = require("../state/editor-snapping");
7
+ const SnappingProvider = ({ children }) => {
8
+ const [editorSnapping, setEditorSnappingState] = (0, react_1.useState)(() => (0, editor_snapping_1.loadEditorSnappingOption)());
9
+ const setEditorSnapping = (0, react_1.useCallback)((newValue) => {
10
+ setEditorSnappingState((prevState) => {
11
+ const newVal = newValue(prevState);
12
+ (0, editor_snapping_1.persistEditorSnappingOption)(newVal);
13
+ return newVal;
14
+ });
15
+ }, []);
16
+ const editorSnappingCtx = (0, react_1.useMemo)(() => {
17
+ return {
18
+ editorSnapping,
19
+ setEditorSnapping,
20
+ };
21
+ }, [editorSnapping, setEditorSnapping]);
22
+ return (jsx_runtime_1.jsx(editor_snapping_1.EditorSnappingContext.Provider, { value: editorSnappingCtx, children: children }));
23
+ };
24
+ exports.SnappingProvider = SnappingProvider;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const SnappingToggle: React.FC;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnappingToggle = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const no_react_1 = require("remotion/no-react");
7
+ const colors_1 = require("../helpers/colors");
8
+ const use_keybinding_1 = require("../helpers/use-keybinding");
9
+ const magnet_1 = require("../icons/magnet");
10
+ const editor_snapping_1 = require("../state/editor-snapping");
11
+ const ControlButton_1 = require("./ControlButton");
12
+ const SnappingToggle = () => {
13
+ const { editorSnapping, setEditorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
14
+ const onClick = (0, react_1.useCallback)(() => {
15
+ setEditorSnapping((current) => !current);
16
+ }, [setEditorSnapping]);
17
+ const color = editorSnapping ? colors_1.BLUE : colors_1.WHITE;
18
+ const accessibilityLabel = [
19
+ editorSnapping ? 'Disable snapping' : 'Enable snapping',
20
+ (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(Shift+M)',
21
+ ]
22
+ .filter(no_react_1.NoReactInternals.truthy)
23
+ .join(' ');
24
+ return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, "aria-pressed": editorSnapping, "aria-keyshortcuts": "Shift+M", onClick: onClick, children: jsx_runtime_1.jsx(magnet_1.MagnetIcon, { style: { width: 17, height: 17 }, fill: color, "aria-hidden": "true", focusable: "false" }) }));
25
+ };
26
+ exports.SnappingToggle = SnappingToggle;
@@ -14,7 +14,7 @@ export type TSplitterContext = {
14
14
  defaultFlex: number;
15
15
  id: string;
16
16
  persistFlex: (value: number) => void;
17
- isDragging: React.MutableRefObject<false | {
17
+ isDragging: React.RefObject<false | {
18
18
  x: number;
19
19
  y: number;
20
20
  }>;
@@ -40,6 +40,7 @@ const remotion_1 = require("remotion");
40
40
  const calculate_timeline_1 = require("../../helpers/calculate-timeline");
41
41
  const client_id_1 = require("../../helpers/client-id");
42
42
  const colors_1 = require("../../helpers/colors");
43
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
43
44
  const is_current_selected_still_1 = require("../../helpers/is-current-selected-still");
44
45
  const open_in_editor_1 = require("../../helpers/open-in-editor");
45
46
  const call_api_1 = require("../call-api");
@@ -88,6 +89,7 @@ const TimelineContextMenuArea = ({ children }) => {
88
89
  const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
89
90
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
90
91
  const previewConnected = previewServerState.type === 'connected';
92
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
91
93
  const currentCompositionId = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
92
94
  const currentComposition = (0, react_1.useMemo)(() => {
93
95
  var _a;
@@ -102,13 +104,13 @@ const TimelineContextMenuArea = ({ children }) => {
102
104
  compositionFile,
103
105
  compositionId: currentCompositionId,
104
106
  });
105
- const canInsertSolid = previewConnected &&
107
+ const canInsertSolid = previewInteractive &&
106
108
  (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
107
109
  currentCompositionId !== null &&
108
110
  compositionFile !== null &&
109
111
  videoConfig !== null &&
110
112
  !isAddingSolid;
111
- const canInsertAsset = previewConnected &&
113
+ const canInsertAsset = previewInteractive &&
112
114
  !window.remotion_isReadOnlyStudio &&
113
115
  (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
114
116
  currentCompositionId !== null &&
@@ -207,6 +209,7 @@ const TimelineInner = () => {
207
209
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
208
210
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
209
211
  const previewConnected = previewServerState.type === 'connected';
212
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
210
213
  const videoConfigIsNull = videoConfig === null;
211
214
  const timeline = (0, react_1.useMemo)(() => {
212
215
  if (videoConfigIsNull) {
@@ -228,15 +231,14 @@ const TimelineInner = () => {
228
231
  }, [filtered]);
229
232
  const hasBeenCut = filtered.length > shown.length;
230
233
  return (jsx_runtime_1.jsxs(TimelineContextMenuArea, { children: [sequences.map((sequence) => {
231
- if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewConnected)) {
234
+ if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewInteractive)) {
232
235
  return null;
233
236
  }
234
237
  return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
235
- }), jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}), jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [
236
- jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown }), jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
238
+ }), interactivity_enabled_1.studioInteractivityEnabled ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsxs(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: [interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown })) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
237
239
  jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, children: [
238
240
  jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
239
- jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
241
+ jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { timeline: shown, hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null, jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
240
242
  ] }) })
241
243
  ] })
242
244
  ] })) })
@@ -38,6 +38,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const player_1 = require("@remotion/player");
39
39
  const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
41
42
  const timeline_layout_1 = require("../../helpers/timeline-layout");
42
43
  const timeline_zoom_1 = require("../../state/timeline-zoom");
43
44
  const z_index_1 = require("../../state/z-index");
@@ -88,7 +89,7 @@ const TimelineDragHandler = () => {
88
89
  if (!canvasContent || canvasContent.type !== 'composition') {
89
90
  return null;
90
91
  }
91
- return (jsx_runtime_1.jsx("div", { ref: timeline_refs_1.sliderAreaRef, style: containerStyle, [TimelineSelection_1.TIMELINE_SCRUBBER_ATTR]: true, children: video ? jsx_runtime_1.jsx(TimelineDragHandlerInnerMemo, {}) : null }));
92
+ return (jsx_runtime_1.jsx("div", { ref: timeline_refs_1.sliderAreaRef, style: containerStyle, [TimelineSelection_1.TIMELINE_SCRUBBER_ATTR]: true, children: video && interactivity_enabled_1.studioInteractivityEnabled ? (jsx_runtime_1.jsx(TimelineDragHandlerInnerMemo, {})) : null }));
92
93
  };
93
94
  exports.TimelineDragHandler = TimelineDragHandler;
94
95
  const TimelineDragHandlerInner = () => {
@@ -7,11 +7,13 @@ const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const client_id_1 = require("../../helpers/client-id");
9
9
  const colors_1 = require("../../helpers/colors");
10
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
10
11
  const timeline_layout_1 = require("../../helpers/timeline-layout");
11
12
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
12
13
  const use_keybinding_1 = require("../../helpers/use-keybinding");
13
14
  const z_index_1 = require("../../state/z-index");
14
15
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
16
+ const options_sidebar_tabs_1 = require("../options-sidebar-tabs");
15
17
  const get_node_keyframes_1 = require("./get-node-keyframes");
16
18
  const get_timeline_easing_segments_1 = require("./get-timeline-easing-segments");
17
19
  const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
@@ -556,7 +558,8 @@ const TimelineSelectionProvider = ({ children }) => {
556
558
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
557
559
  const timelineSelectionScope = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
558
560
  const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
559
- const canSelect = previewServerState.type === 'connected' &&
561
+ const canSelect = interactivity_enabled_1.studioInteractivityEnabled &&
562
+ previewServerState.type === 'connected' &&
560
563
  !window.remotion_isReadOnlyStudio;
561
564
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
562
565
  const selectionAnchor = (0, react_1.useRef)(null);
@@ -684,6 +687,7 @@ const TimelineSelectionProvider = ({ children }) => {
684
687
  if (!canSelectItem(item)) {
685
688
  return;
686
689
  }
690
+ (0, options_sidebar_tabs_1.selectOptionsSidebarInspectorPanel)();
687
691
  expandParentsForSelectionItem(item);
688
692
  if (options.reveal) {
689
693
  requestRevealSelectionItem(item);
@@ -714,6 +718,9 @@ const TimelineSelectionProvider = ({ children }) => {
714
718
  if (!items.every(canSelectItem)) {
715
719
  return;
716
720
  }
721
+ if (items.length > 0) {
722
+ (0, options_sidebar_tabs_1.selectOptionsSidebarInspectorPanel)();
723
+ }
717
724
  selectionScope.current = timelineSelectionScope;
718
725
  selectionAnchor.current =
719
726
  items.length === 0 ? null : items[items.length - 1];
@@ -41,6 +41,7 @@ const client_id_1 = require("../../helpers/client-id");
41
41
  const colors_1 = require("../../helpers/colors");
42
42
  const format_file_location_1 = require("../../helpers/format-file-location");
43
43
  const get_timeline_sequence_layout_1 = require("../../helpers/get-timeline-sequence-layout");
44
+ const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
44
45
  const open_in_editor_1 = require("../../helpers/open-in-editor");
45
46
  const timeline_layout_1 = require("../../helpers/timeline-layout");
46
47
  const use_max_media_duration_1 = require("../../helpers/use-max-media-duration");
@@ -177,11 +178,15 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
177
178
  ? remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)
178
179
  : undefined;
179
180
  }, [propStatuses, nodePath]);
180
- const durationCanUpdate = Boolean(((_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames) === null || _a === void 0 ? void 0 : _a.status) === 'static');
181
- const fromCanUpdate = Boolean(((_b = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.from) === null || _b === void 0 ? void 0 : _b.status) === 'static');
182
- const trimBeforeCanUpdate = Boolean(((_c = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.trimBefore) === null || _c === void 0 ? void 0 : _c.status) === 'static');
181
+ const durationCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
182
+ ((_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.durationInFrames) === null || _a === void 0 ? void 0 : _a.status) === 'static');
183
+ const fromCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
184
+ ((_b = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.from) === null || _b === void 0 ? void 0 : _b.status) === 'static');
185
+ const trimBeforeCanUpdate = Boolean(interactivity_enabled_1.studioInteractivityEnabled &&
186
+ ((_c = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.trimBefore) === null || _c === void 0 ? void 0 : _c.status) === 'static');
183
187
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
184
188
  const previewConnected = previewServerState.type === 'connected';
189
+ const previewInteractive = previewConnected && interactivity_enabled_1.studioInteractivityEnabled;
185
190
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
186
191
  const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
187
192
  const selectAsset = (0, use_select_asset_1.useSelectAsset)();
@@ -201,9 +206,9 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
201
206
  });
202
207
  }, [canOpenInEditor, originalLocation]);
203
208
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
204
- const deleteDisabled = !previewConnected || !s.controls || !canDeleteFromSource;
209
+ const deleteDisabled = !previewInteractive || !s.controls || !canDeleteFromSource;
205
210
  const duplicateDisabled = deleteDisabled;
206
- const disableInteractivityDisabled = !previewConnected ||
211
+ const disableInteractivityDisabled = !previewInteractive ||
207
212
  !s.showInTimeline ||
208
213
  !nodePath ||
209
214
  !(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source);
@@ -280,7 +285,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
280
285
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
281
286
  ]);
282
287
  const freezeFrameMenuItem = (0, use_sequence_freeze_frame_menu_item_1.useSequenceFreezeFrameMenuItem)({
283
- clientId: previewServerState.type === 'connected'
288
+ clientId: previewInteractive && previewServerState.type === 'connected'
284
289
  ? previewServerState.clientId
285
290
  : null,
286
291
  nodePath,
@@ -302,7 +307,7 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
302
307
  disableInteractivityDisabled,
303
308
  duplicateDisabled,
304
309
  fileLocation,
305
- includeSourceEditItems: true,
310
+ includeSourceEditItems: interactivity_enabled_1.studioInteractivityEnabled,
306
311
  onDeleteSequenceFromSource,
307
312
  onDisableSequenceInteractivity,
308
313
  onDuplicateSequenceFromSource,
@@ -310,7 +315,9 @@ const TimelineSequenceInner = ({ s, windowWidth, nodePathInfo, sequenceFrameOffs
310
315
  originalLocation,
311
316
  selectAsset,
312
317
  sequence: s,
313
- sourceActions: freezeFrameMenuItem ? [freezeFrameMenuItem] : [],
318
+ sourceActions: interactivity_enabled_1.studioInteractivityEnabled && freezeFrameMenuItem
319
+ ? [freezeFrameMenuItem]
320
+ : [],
314
321
  });
315
322
  }, [
316
323
  assetLinkInfo,