@remotion/studio 4.0.512 → 4.0.514

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 (208) hide show
  1. package/dist/Studio.js +2 -1
  2. package/dist/components/AskAiModal.js +1 -1
  3. package/dist/components/AssetSelector.js +2 -0
  4. package/dist/components/AssetSelectorItem.js +1 -2
  5. package/dist/components/AudioWaveform.d.ts +3 -0
  6. package/dist/components/AudioWaveform.js +55 -67
  7. package/dist/components/Canvas.js +40 -5
  8. package/dist/components/CanvasOrLoading.js +5 -0
  9. package/dist/components/CompositionSelector.js +2 -0
  10. package/dist/components/CompositionSelectorItem.js +14 -1
  11. package/dist/components/ConfigureDefaultEditorModal.js +17 -11
  12. package/dist/components/Editor.js +16 -1
  13. package/dist/components/ElementInstallConfirmation.d.ts +1 -0
  14. package/dist/components/ElementInstallConfirmation.js +4 -2
  15. package/dist/components/FixComputedValueModal.d.ts +9 -0
  16. package/dist/components/FixComputedValueModal.js +217 -0
  17. package/dist/components/InitialCompositionLoader.js +19 -0
  18. package/dist/components/InlineDropdown.js +4 -4
  19. package/dist/components/InspectorInfoHeader.js +3 -3
  20. package/dist/components/InspectorOpenInEditor.js +26 -24
  21. package/dist/components/InspectorPanel/AlignmentControls.js +13 -2
  22. package/dist/components/InspectorPanel/CompositionInspector.js +11 -1
  23. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +12 -8
  24. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +13 -2
  25. package/dist/components/InspectorPanel/EasingInspector.js +12 -3
  26. package/dist/components/InspectorPanel/KeyframeInspector.js +21 -7
  27. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +1 -1
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +35 -6
  29. package/dist/components/InspectorPanel/common.d.ts +5 -5
  30. package/dist/components/InspectorPanel/common.js +8 -8
  31. package/dist/components/InspectorPanel/easing-inspector-selection.js +7 -2
  32. package/dist/components/InspectorPanel/inspector-section-collapse.d.ts +1 -0
  33. package/dist/components/InspectorPanel/styles.d.ts +1 -1
  34. package/dist/components/InspectorPanel/styles.js +4 -2
  35. package/dist/components/InspectorSourceLocation.d.ts +1 -1
  36. package/dist/components/InspectorSourceLocation.js +2 -2
  37. package/dist/components/LicenseKeyValidation.js +2 -2
  38. package/dist/components/Modals.js +2 -1
  39. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  40. package/dist/components/NewComposition/CodemodFooter.js +10 -8
  41. package/dist/components/NewComposition/DeleteComposition.js +1 -1
  42. package/dist/components/NewComposition/DeleteFolder.js +1 -1
  43. package/dist/components/NewComposition/DuplicateComposition.js +7 -2
  44. package/dist/components/NewComposition/NewComposition.js +1 -1
  45. package/dist/components/NewComposition/NewFolder.js +1 -1
  46. package/dist/components/NewComposition/RenameComposition.js +1 -1
  47. package/dist/components/NewComposition/RenameFolder.js +1 -1
  48. package/dist/components/NewComposition/duplicate-composition-api.d.ts +16 -0
  49. package/dist/components/NewComposition/duplicate-composition-api.js +16 -0
  50. package/dist/components/NoRegisterRoot.js +1 -1
  51. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +4 -3
  52. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  53. package/dist/components/QuickSwitcher/fuzzy-search.js +1 -1
  54. package/dist/components/RefreshCompositionOverlay.js +1 -1
  55. package/dist/components/RenderButton.js +6 -3
  56. package/dist/components/RenderModal/WebRenderModal.js +6 -2
  57. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +2 -0
  58. package/dist/components/RenderModal/WebRenderModalAdvanced.js +9 -2
  59. package/dist/components/RenderModal/render-modals.js +5 -1
  60. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +5 -1
  61. package/dist/components/RenderQueue/actions.js +12 -2
  62. package/dist/components/RenderQueue/client-side-render-types.d.ts +1 -0
  63. package/dist/components/RenderingSettings.d.ts +2 -0
  64. package/dist/components/RenderingSettings.js +355 -0
  65. package/dist/components/SelectedOutlineElement.js +15 -13
  66. package/dist/components/SelectedOutlineOverlay.js +30 -8
  67. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  68. package/dist/components/SelectedOutlinePolygon.js +53 -9
  69. package/dist/components/SettingsContext.d.ts +4 -1
  70. package/dist/components/SettingsContext.js +9 -2
  71. package/dist/components/SettingsModal.d.ts +1 -1
  72. package/dist/components/SettingsModal.js +10 -1
  73. package/dist/components/SettingsModalFooter.js +1 -1
  74. package/dist/components/StudioSettings.d.ts +2 -0
  75. package/dist/components/StudioSettings.js +185 -0
  76. package/dist/components/Timeline/LoopedIndicator.js +1 -1
  77. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +3 -0
  78. package/dist/components/Timeline/LoopedTimelineIndicators.js +22 -14
  79. package/dist/components/Timeline/Timeline.js +11 -9
  80. package/dist/components/Timeline/TimelineArrayField.js +1 -0
  81. package/dist/components/Timeline/TimelineAssetField.d.ts +2 -2
  82. package/dist/components/Timeline/TimelineAssetField.js +1 -1
  83. package/dist/components/Timeline/TimelineDragHandler.js +62 -76
  84. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  85. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +4 -2
  86. package/dist/components/Timeline/TimelineEffectPropItem.js +25 -14
  87. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -1
  88. package/dist/components/Timeline/TimelineExpandedRow.js +4 -4
  89. package/dist/components/Timeline/TimelineExpandedSection.js +1 -1
  90. package/dist/components/Timeline/TimelineHeightContainer.d.ts +0 -4
  91. package/dist/components/Timeline/TimelineHeightContainer.js +4 -4
  92. package/dist/components/Timeline/TimelineImageInfo.d.ts +1 -0
  93. package/dist/components/Timeline/TimelineImageInfo.js +3 -2
  94. package/dist/components/Timeline/TimelineKeyframeControls.js +31 -8
  95. package/dist/components/Timeline/TimelineKeyframedValue.js +1 -0
  96. package/dist/components/Timeline/TimelineList.d.ts +1 -5
  97. package/dist/components/Timeline/TimelineList.js +14 -9
  98. package/dist/components/Timeline/TimelinePinchZoom.js +5 -5
  99. package/dist/components/Timeline/TimelineRowChrome.d.ts +0 -2
  100. package/dist/components/Timeline/TimelineRowChrome.js +12 -5
  101. package/dist/components/Timeline/TimelineSchemaField.d.ts +7 -3
  102. package/dist/components/Timeline/TimelineSchemaField.js +71 -13
  103. package/dist/components/Timeline/TimelineScrollable.js +3 -1
  104. package/dist/components/Timeline/TimelineSelection.d.ts +5 -2
  105. package/dist/components/Timeline/TimelineSelection.js +90 -103
  106. package/dist/components/Timeline/TimelineSequence.js +59 -25
  107. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -1
  108. package/dist/components/Timeline/TimelineSequenceItem.js +15 -9
  109. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +2 -1
  110. package/dist/components/Timeline/TimelineSequencePropItem.js +14 -7
  111. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +3 -0
  112. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +128 -27
  113. package/dist/components/Timeline/TimelineSlider.js +42 -33
  114. package/dist/components/Timeline/TimelineTimeIndicators.js +90 -98
  115. package/dist/components/Timeline/TimelineTracks.d.ts +0 -2
  116. package/dist/components/Timeline/TimelineTracks.js +11 -4
  117. package/dist/components/Timeline/TimelineTransformOriginField.js +1 -1
  118. package/dist/components/Timeline/TimelineVideoInfo.d.ts +4 -4
  119. package/dist/components/Timeline/TimelineVideoInfo.js +151 -61
  120. package/dist/components/Timeline/TimelineViewport.d.ts +12 -0
  121. package/dist/components/Timeline/TimelineViewport.js +62 -0
  122. package/dist/components/Timeline/TimelineVirtualization.d.ts +22 -0
  123. package/dist/components/Timeline/TimelineVirtualization.js +144 -0
  124. package/dist/components/Timeline/TimelineZoomControls.js +16 -8
  125. package/dist/components/Timeline/call-add-keyframe.js +31 -3
  126. package/dist/components/Timeline/call-delete-keyframe.js +13 -3
  127. package/dist/components/Timeline/call-move-keyframe.d.ts +2 -1
  128. package/dist/components/Timeline/call-move-keyframe.js +81 -18
  129. package/dist/components/Timeline/call-update-keyframe-settings.js +31 -3
  130. package/dist/components/Timeline/delete-selected-keyframe.d.ts +0 -8
  131. package/dist/components/Timeline/delete-selected-keyframe.js +23 -44
  132. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +0 -8
  133. package/dist/components/Timeline/delete-selected-timeline-item.js +18 -44
  134. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +8 -3
  135. package/dist/components/Timeline/get-sequence-context-menu-items.js +10 -8
  136. package/dist/components/Timeline/get-timeline-keyframes.d.ts +5 -2
  137. package/dist/components/Timeline/get-timeline-keyframes.js +16 -10
  138. package/dist/components/Timeline/get-timeline-sequence-visible-layout.d.ts +30 -0
  139. package/dist/components/Timeline/get-timeline-sequence-visible-layout.js +61 -0
  140. package/dist/components/Timeline/keyframe-clipboard.js +9 -2
  141. package/dist/components/Timeline/split-selected-timeline-item.js +2 -2
  142. package/dist/components/Timeline/timeline-scroll-logic.d.ts +24 -0
  143. package/dist/components/Timeline/timeline-scroll-logic.js +127 -4
  144. package/dist/components/Timeline/use-open-sequence-in-apps.js +8 -8
  145. package/dist/components/Timeline/use-timeline-height.d.ts +3 -5
  146. package/dist/components/Timeline/use-timeline-height.js +16 -18
  147. package/dist/components/Timeline/use-timeline-keyframe-drag.js +14 -4
  148. package/dist/components/UpdateCheck.d.ts +2 -10
  149. package/dist/components/UpdateCheck.js +8 -2
  150. package/dist/components/VisualControls/ClickableFileName.js +13 -6
  151. package/dist/components/VisualControls/VisualControlHandle.js +8 -0
  152. package/dist/components/composition-menu-items.d.ts +6 -1
  153. package/dist/components/composition-menu-items.js +9 -6
  154. package/dist/components/delete-jsx-node-api.d.ts +2 -0
  155. package/dist/components/delete-jsx-node-api.js +12 -0
  156. package/dist/components/element-install-api.d.ts +3 -0
  157. package/dist/components/element-install-api.js +19 -0
  158. package/dist/components/folder-menu-items.d.ts +4 -1
  159. package/dist/components/folder-menu-items.js +4 -5
  160. package/dist/components/get-open-in-menu-items.d.ts +1 -1
  161. package/dist/components/get-open-in-menu-items.js +15 -13
  162. package/dist/components/import-assets.js +20 -9
  163. package/dist/components/reorder-sequence-api.d.ts +2 -0
  164. package/dist/components/reorder-sequence-api.js +12 -0
  165. package/dist/components/sequence-props-api.js +44 -3
  166. package/dist/components/split-jsx-sequence-api.d.ts +2 -0
  167. package/dist/components/split-jsx-sequence-api.js +12 -0
  168. package/dist/components/split-video-from-audio-api.d.ts +2 -0
  169. package/dist/components/split-video-from-audio-api.js +12 -0
  170. package/dist/components/use-default-editor-info.d.ts +8 -0
  171. package/dist/components/use-default-editor-info.js +25 -9
  172. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +10 -3
  173. package/dist/error-overlay/remotion-overlay/OpenInEditor.d.ts +3 -1
  174. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +6 -6
  175. package/dist/error-overlay/remotion-overlay/Overlay.js +14 -12
  176. package/dist/error-overlay/remotion-overlay/StackFrame.d.ts +2 -1
  177. package/dist/error-overlay/remotion-overlay/StackFrame.js +7 -4
  178. package/dist/esm/{chunk-s8gwjng0.js → chunk-xn2q7eem.js} +11983 -8035
  179. package/dist/esm/index.mjs +7 -5
  180. package/dist/esm/internals.mjs +11983 -8035
  181. package/dist/esm/previewEntry.mjs +13059 -9107
  182. package/dist/esm/renderEntry.mjs +2 -3
  183. package/dist/helpers/browser-studio-operations.d.ts +2 -0
  184. package/dist/helpers/browser-studio-operations.js +10 -1
  185. package/dist/helpers/get-timeline-max-zoom.d.ts +26 -0
  186. package/dist/helpers/get-timeline-max-zoom.js +45 -0
  187. package/dist/helpers/inject-css.js +2 -2
  188. package/dist/helpers/open-in-editor.d.ts +6 -4
  189. package/dist/helpers/open-in-editor.js +4 -4
  190. package/dist/helpers/render-codec-label.d.ts +1 -1
  191. package/dist/helpers/retry-payload.js +1 -0
  192. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  193. package/dist/helpers/studio-runtime-config.js +2 -3
  194. package/dist/helpers/timeline-layout.d.ts +3 -1
  195. package/dist/helpers/timeline-layout.js +6 -1
  196. package/dist/helpers/url-state.js +3 -2
  197. package/dist/helpers/use-menu-structure.js +12 -11
  198. package/dist/helpers/use-runtime-values.d.ts +2 -1
  199. package/dist/helpers/use-runtime-values.js +7 -3
  200. package/dist/icons/remotion-triangle.d.ts +2 -0
  201. package/dist/icons/remotion-triangle.js +7 -0
  202. package/dist/renderEntry.js +1 -1
  203. package/dist/state/composition-list.d.ts +13 -0
  204. package/dist/state/composition-list.js +21 -0
  205. package/dist/state/modals.d.ts +7 -1
  206. package/dist/state/timeline-zoom.d.ts +1 -2
  207. package/dist/state/timeline-zoom.js +9 -5
  208. package/package.json +14 -13
@@ -9,11 +9,11 @@ const timeline_zoom_1 = require("../../state/timeline-zoom");
9
9
  const timeline_refs_1 = require("./timeline-refs");
10
10
  const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
11
11
  /**
12
- * Maps wheel deltaY to zoom delta. Must be large enough that typical ctrl+wheel
13
- * pinch steps change `TimelineZoomCtx` zoom by at least one 0.1 step after
14
- * `Math.round(z * 10) / 10` in `timeline-zoom.tsx` (0.005 was too small).
12
+ * Maps wheel deltaY to a multiplicative zoom change. Must be large enough that
13
+ * typical ctrl+wheel pinch steps change `TimelineZoomCtx` zoom by at least one
14
+ * 0.1 step after rounding in `clampTimelineZoom` (0.005 was too small at 1x).
15
15
  */
16
- const ZOOM_WHEEL_DELTA = 0.06;
16
+ const ZOOM_WHEEL_SENSITIVITY = 0.06;
17
17
  const TimelinePinchZoom = () => {
18
18
  const isVideoComposition = (0, is_current_selected_still_1.useIsVideoComposition)();
19
19
  const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
@@ -60,7 +60,7 @@ const TimelinePinchZoom = () => {
60
60
  else if (deltaMode === WheelEvent.DOM_DELTA_PAGE) {
61
61
  scaledDeltaY *= scrollEl.clientHeight;
62
62
  }
63
- setZoom(canvasContent.compositionId, (z) => z - scaledDeltaY * ZOOM_WHEEL_DELTA, { anchorFrame: null, anchorContentX });
63
+ setZoom(canvasContent.compositionId, (z) => z * Math.exp(-scaledDeltaY * ZOOM_WHEEL_SENSITIVITY), { anchorFrame: null, anchorContentX });
64
64
  }, [
65
65
  editorZoomGestures,
66
66
  isVideoComposition,
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { TimelineSelectionInteraction } from './TimelineSelection';
3
- import { type TimelineSelection } from './TimelineSelection';
4
3
  export declare const TimelineRowKeyframeControlsColumn: React.FC<{
5
4
  readonly children: React.ReactNode;
6
5
  readonly depth: number;
@@ -14,7 +13,6 @@ export declare const TimelineRowChrome: React.FC<{
14
13
  readonly style: React.CSSProperties;
15
14
  readonly selected: boolean;
16
15
  readonly selectable: boolean;
17
- readonly selectionItem: TimelineSelection | null;
18
16
  readonly onSelect: (interaction?: TimelineSelectionInteraction) => void;
19
17
  readonly showSelectedBackground: boolean;
20
18
  readonly containsSelection: boolean;
@@ -35,11 +35,9 @@ const TimelineRowKeyframeControlsColumn = ({ children, depth }) => {
35
35
  return (jsx_runtime_1.jsx("div", { style: leftChromeStyle, children: jsx_runtime_1.jsx("div", { style: style, children: children }) }));
36
36
  };
37
37
  exports.TimelineRowKeyframeControlsColumn = TimelineRowKeyframeControlsColumn;
38
- const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, style, selected, selectable, selectionItem, onSelect, showSelectedBackground, containsSelection, hovered = false, isFieldRow, outerHeight, onDragLeave, onDragOver, onDrop, onDoubleClick, onPointerEnter, onPointerLeave, }) => {
39
- const ref = (0, react_1.useRef)(null);
38
+ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, style, selected, selectable, onSelect, showSelectedBackground, containsSelection, hovered = false, isFieldRow, outerHeight, onDragLeave, onDragOver, onDrop, onDoubleClick, onPointerEnter, onPointerLeave, }) => {
40
39
  const { basePadding, keyframeControlsPlacement, rowBorderRadius, rowHorizontalMargin, } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
41
40
  const indentWidth = (0, timeline_row_layout_1.getTimelineRowIndentWidth)(depth);
42
- (0, TimelineSelection_1.useTimelineFocusableItem)(selectionItem, ref);
43
41
  const chromeColumnStyle = (0, react_1.useMemo)(() => ({
44
42
  alignItems: 'center',
45
43
  alignSelf: 'stretch',
@@ -60,6 +58,15 @@ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, styl
60
58
  e.stopPropagation();
61
59
  onSelect();
62
60
  }, [onSelect]);
61
+ const onDoubleClickIfNotInteractive = (0, react_1.useCallback)((e) => {
62
+ const { target } = e;
63
+ if (target instanceof Element &&
64
+ e.currentTarget.contains(target.closest('button, input, select, textarea, a, [contenteditable="true"]'))) {
65
+ e.stopPropagation();
66
+ return;
67
+ }
68
+ onDoubleClick === null || onDoubleClick === void 0 ? void 0 : onDoubleClick(e);
69
+ }, [onDoubleClick]);
63
70
  const highlightBackground = (0, TimelineSelection_1.getTimelineRowHighlightBackground)({
64
71
  showSelectedBackground,
65
72
  selected,
@@ -95,8 +102,8 @@ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, styl
95
102
  const shouldRenderLeftChrome = !isFieldRow || keyframeControlsPlacement === 'before-label';
96
103
  const chrome = (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [shouldRenderLeftChrome ? (keyframeControls ? (jsx_runtime_1.jsx(exports.TimelineRowKeyframeControlsColumn, { depth: depth, children: keyframeControls })) : (jsx_runtime_1.jsx("div", { style: leftChromeStyle, children: jsx_runtime_1.jsxs("div", { style: chromeColumnStyle, children: [eye, indentWidth > 0 ? jsx_runtime_1.jsx(Padder_1.Padder, { depth: depth }) : null, arrow] }) }))) : null, children] }));
97
104
  if (outerStyle) {
98
- return (jsx_runtime_1.jsx("div", { ref: ref, style: outerStyle, onDragLeave: onDragLeave, onDragOver: onDragOver, onDrop: onDrop, onPointerDown: selectable ? onPointerDown : undefined, onContextMenu: selectable ? onContextMenu : undefined, onDoubleClick: onDoubleClick, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsx("div", { style: innerRowStyle, children: chrome }) }));
105
+ return (jsx_runtime_1.jsx("div", { style: outerStyle, onDragLeave: onDragLeave, onDragOver: onDragOver, onDrop: onDrop, onPointerDown: selectable ? onPointerDown : undefined, onContextMenu: selectable ? onContextMenu : undefined, onDoubleClick: onDoubleClickIfNotInteractive, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsx("div", { style: innerRowStyle, children: chrome }) }));
99
106
  }
100
- return (jsx_runtime_1.jsx("div", { ref: ref, onDragLeave: onDragLeave, onDragOver: onDragOver, onDrop: onDrop, onPointerDown: selectable ? onPointerDown : undefined, onContextMenu: selectable ? onContextMenu : undefined, onDoubleClick: onDoubleClick, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, style: innerRowStyle, children: chrome }));
107
+ return (jsx_runtime_1.jsx("div", { onDragLeave: onDragLeave, onDragOver: onDragOver, onDrop: onDrop, onPointerDown: selectable ? onPointerDown : undefined, onContextMenu: selectable ? onContextMenu : undefined, onDoubleClick: onDoubleClickIfNotInteractive, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, style: innerRowStyle, children: chrome }));
101
108
  };
102
109
  exports.TimelineRowChrome = TimelineRowChrome;
@@ -1,13 +1,17 @@
1
1
  import React from 'react';
2
2
  import type { CanUpdateSequencePropStatusFalse, CanUpdateSequencePropStatusStatic, SequencePropsSubscriptionKey } from 'remotion';
3
+ import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
3
4
  import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSave } from '../../helpers/timeline-layout';
4
- export declare const TIMELINE_COMPUTED_EFFECT_FIX_LINK = "https://www.remotion.dev/docs/studio/interactivity-best-practices#keep-effects-editable";
5
5
  export declare const UnsupportedStatus: React.FC<{
6
- readonly label: string;
7
- readonly fixHref?: string;
6
+ readonly label: React.ReactNode;
7
+ readonly onFix?: () => void;
8
+ readonly formattedValue: boolean;
8
9
  }>;
9
10
  export declare const TimelineNonEditableStatus: React.FC<{
10
11
  readonly propStatus: CanUpdateSequencePropStatusFalse;
12
+ readonly field: SchemaFieldInfo;
13
+ readonly runtimeValue: unknown;
14
+ readonly validatedLocation: CodePosition;
11
15
  }>;
12
16
  export declare const TimelineFieldValue: React.FC<{
13
17
  readonly field: SchemaFieldInfo;
@@ -1,18 +1,47 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
5
35
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TimelineFieldValue = exports.TimelineNonEditableStatus = exports.UnsupportedStatus = exports.TIMELINE_COMPUTED_EFFECT_FIX_LINK = void 0;
36
+ exports.TimelineFieldValue = exports.TimelineNonEditableStatus = exports.UnsupportedStatus = void 0;
7
37
  const jsx_runtime_1 = require("react/jsx-runtime");
8
- const react_1 = __importDefault(require("react"));
38
+ const react_1 = __importStar(require("react"));
9
39
  const colors_1 = require("../../helpers/colors");
10
- const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
40
+ const modals_1 = require("../../state/modals");
41
+ const SettingsContext_1 = require("../SettingsContext");
42
+ const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
11
43
  const TimelineArrayField_1 = require("./TimelineArrayField");
12
44
  const TimelinePrimitiveFieldValue_1 = require("./TimelinePrimitiveFieldValue");
13
- const INTERACTIVITY_BEST_PRACTICES_DOCS = 'https://www.remotion.dev/docs/studio/interactivity-best-practices';
14
- const TIMELINE_COMPUTED_VALUE_FIX_LINK = `${INTERACTIVITY_BEST_PRACTICES_DOCS}#keep-editable-values-visible`;
15
- exports.TIMELINE_COMPUTED_EFFECT_FIX_LINK = `${INTERACTIVITY_BEST_PRACTICES_DOCS}#keep-effects-editable`;
16
45
  const unsupportedStatusWrapper = {
17
46
  alignItems: 'center',
18
47
  display: 'inline-flex',
@@ -25,6 +54,13 @@ const unsupportedLabel = {
25
54
  fontSize: 12,
26
55
  fontStyle: 'italic',
27
56
  };
57
+ const computedValue = {
58
+ color: colors_1.WHITE_ALPHA_40,
59
+ fontFamily: 'Arial, Helvetica, sans-serif',
60
+ fontSize: 12,
61
+ lineHeight: '18px',
62
+ pointerEvents: 'none',
63
+ };
28
64
  const fixLinkBase = {
29
65
  color: colors_1.LIGHT_TEXT,
30
66
  display: 'inline-block',
@@ -34,8 +70,13 @@ const fixLinkBase = {
34
70
  lineHeight: 1,
35
71
  textDecoration: 'none',
36
72
  width: 17,
73
+ appearance: 'none',
74
+ background: 'none',
75
+ border: 'none',
76
+ cursor: 'pointer',
77
+ padding: 0,
37
78
  };
38
- const UnsupportedStatus = ({ label, fixHref }) => {
79
+ const UnsupportedStatus = ({ label, onFix, formattedValue }) => {
39
80
  const [hovered, setHovered] = react_1.default.useState(false);
40
81
  const [focused, setFocused] = react_1.default.useState(false);
41
82
  const visible = hovered || focused;
@@ -53,12 +94,29 @@ const UnsupportedStatus = ({ label, fixHref }) => {
53
94
  event.stopPropagation();
54
95
  };
55
96
  return (jsx_runtime_1.jsxs("span", { style: unsupportedStatusWrapper, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), children: [
56
- jsx_runtime_1.jsx("span", { style: unsupportedLabel, children: label }), fixHref ? (jsx_runtime_1.jsx("a", { href: fixHref, target: "_blank", rel: "noreferrer", style: fixLink, title: "Open docs to fix computed Studio values", onClick: stopMousePropagation, onDoubleClick: stopMousePropagation, onPointerDown: stopPointerPropagation, onFocus: () => setFocused(true), onBlur: () => setFocused(false), tabIndex: visible ? 0 : -1, children: "Fix" })) : null] }));
97
+ jsx_runtime_1.jsx("span", { style: formattedValue ? computedValue : unsupportedLabel, inert: formattedValue, children: label }), onFix ? (jsx_runtime_1.jsx("button", { type: "button", style: fixLink, title: "Fix computed Studio value", onClick: (event) => {
98
+ stopMousePropagation(event);
99
+ onFix();
100
+ }, onDoubleClick: stopMousePropagation, onPointerDown: stopPointerPropagation, onFocus: () => setFocused(true), onBlur: () => setFocused(false), tabIndex: visible ? 0 : -1, children: "Fix" })) : null] }));
57
101
  };
58
102
  exports.UnsupportedStatus = UnsupportedStatus;
59
- const TimelineNonEditableStatus = ({ propStatus }) => {
103
+ const TimelineNonEditableStatus = ({ propStatus, field, runtimeValue, validatedLocation }) => {
104
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
105
+ const { remotionSkillsInfo } = (0, SettingsContext_1.useSettings)();
106
+ const onFix = (0, react_1.useCallback)(() => {
107
+ var _a;
108
+ setSelectedModal({
109
+ type: 'fix-computed-value',
110
+ prop: field.key,
111
+ context: `${validatedLocation.source}:${validatedLocation.line}:${validatedLocation.column}`,
112
+ remotionInteractivitySkillAvailable: (_a = remotionSkillsInfo === null || remotionSkillsInfo === void 0 ? void 0 : remotionSkillsInfo.remotionInteractivitySkillAvailable) !== null && _a !== void 0 ? _a : false,
113
+ });
114
+ }, [field.key, remotionSkillsInfo, setSelectedModal, validatedLocation]);
60
115
  if (propStatus.status === 'computed') {
61
- return (jsx_runtime_1.jsx(exports.UnsupportedStatus, { label: (0, get_timeline_keyframes_1.getComputedStatusLabel)(propStatus), fixHref: TIMELINE_COMPUTED_VALUE_FIX_LINK }));
116
+ return (jsx_runtime_1.jsx(exports.UnsupportedStatus, { label: (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
117
+ fieldSchema: field.fieldSchema,
118
+ value: runtimeValue,
119
+ }), onFix: onFix, formattedValue: true }));
62
120
  }
63
121
  };
64
122
  exports.TimelineNonEditableStatus = TimelineNonEditableStatus;
@@ -8,11 +8,13 @@ const is_menu_item_1 = require("../Menu/is-menu-item");
8
8
  const timeline_refs_1 = require("./timeline-refs");
9
9
  const TimelineAssetDropIndicator_1 = require("./TimelineAssetDropIndicator");
10
10
  const TimelineSelection_1 = require("./TimelineSelection");
11
+ const TimelineViewport_1 = require("./TimelineViewport");
11
12
  const outer = {
12
13
  width: '100%',
13
14
  height: '100%',
14
15
  overflowX: 'auto',
15
16
  overflowY: 'hidden',
17
+ overscrollBehaviorX: 'none',
16
18
  position: 'relative',
17
19
  backgroundColor: TimelineSelection_1.TIMELINE_BACKGROUND,
18
20
  };
@@ -33,7 +35,7 @@ const TimelineScrollable = ({ children }) => {
33
35
  };
34
36
  }, []);
35
37
  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: {
38
+ jsx_runtime_1.jsx(TimelineViewport_1.TimelineViewportProvider, { scrollable: timeline_refs_1.scrollableRef, children: 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: {
37
39
  ...marqueeStyle,
38
40
  height: marqueeRect.bottom - marqueeRect.top,
39
41
  left: marqueeRect.left,
@@ -125,12 +125,12 @@ export declare const extendTimelineMarqueeSelection: ({ currentSelection, marque
125
125
  }) => readonly TimelineSelection[];
126
126
  type TimelineSelectionContextValue = {
127
127
  readonly canSelect: boolean;
128
+ readonly revealRequest: TimelineSelectionRevealRequest | null;
128
129
  readonly selectedItems: readonly TimelineSelection[];
129
130
  readonly isSelected: (item: TimelineSelection) => boolean;
130
131
  readonly selectItem: (item: TimelineSelection, interaction?: TimelineSelectionInteraction, allSelectableItems?: readonly TimelineSelection[], options?: TimelineSelectionOptions) => void;
131
132
  readonly selectItems: (items: readonly TimelineSelection[], options?: TimelineSelectionOptions) => void;
132
133
  readonly registerMarqueeSelectableItem: (item: TimelineSelection, getRect: () => DOMRect | null) => () => void;
133
- readonly registerFocusableItem: (item: TimelineSelection, getElement: () => Element | null) => () => void;
134
134
  readonly getMarqueeSelection: (marqueeRect: TimelineMarqueeRect, lockedSelectionKind: TimelineMarqueeSelectionKind | null) => {
135
135
  readonly lockedSelectionKind: TimelineMarqueeSelectionKind | null;
136
136
  readonly selectedItems: readonly TimelineSelection[];
@@ -145,6 +145,10 @@ export declare const TimelineSelectionOrderProvider: React.FC<{
145
145
  type TimelineSelectionOptions = {
146
146
  readonly reveal?: boolean;
147
147
  };
148
+ type TimelineSelectionRevealRequest = {
149
+ readonly item: TimelineSelection;
150
+ readonly token: number;
151
+ };
148
152
  export declare const getTimelineSelectionFromNodePathInfo: (nodePathInfo: SequenceNodePathInfo | null) => TimelineSelection | null;
149
153
  export declare const getTimelineSelectionKey: (item: TimelineSelection) => string;
150
154
  export declare const getSelectableTimelineSequenceSelections: (tracks: readonly Pick<TimelineTrackData, "nodePathInfo">[]) => TimelineSelection[];
@@ -181,7 +185,6 @@ export declare const useTimelineMarqueeSelection: () => {
181
185
  onPointerDownCapture: (event: React.PointerEvent<HTMLDivElement>) => void;
182
186
  };
183
187
  export declare const useTimelineMarqueeSelectableItem: (item: TimelineSelection | null, ref: React.RefObject<Element | null>) => void;
184
- export declare const useTimelineFocusableItem: (item: TimelineSelection | null, ref: React.RefObject<Element | null>) => void;
185
188
  export declare const useTimelineRowSelection: (nodePathInfo: SequenceNodePathInfo | null) => {
186
189
  onSelect: (interaction?: TimelineSelectionInteraction | undefined) => void;
187
190
  selectable: boolean;
@@ -1,10 +1,11 @@
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.getTimelineSequenceSelectionForEscape = 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_HOVER_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
3
+ exports.useTimelineRowHighlightBackground = exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.getTimelineSequenceSelectionForEscape = 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_HOVER_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");
7
7
  const remotion_1 = require("remotion");
8
+ const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
8
9
  const client_id_1 = require("../../helpers/client-id");
9
10
  const colors_1 = require("../../helpers/colors");
10
11
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
@@ -21,6 +22,7 @@ const imperative_state_1 = require("./imperative-state");
21
22
  const parse_keyframe_field_from_node_path_1 = require("./parse-keyframe-field-from-node-path");
22
23
  const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
23
24
  const timeline_refs_1 = require("./timeline-refs");
25
+ const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
24
26
  const TimelineClipboardKeybindings_1 = require("./TimelineClipboardKeybindings");
25
27
  const TimelineDeleteKeybindings_1 = require("./TimelineDeleteKeybindings");
26
28
  exports.TIMELINE_SELECTED_BACKGROUND = colors_1.TIMELINE_SELECTED_BACKGROUND_COLOR;
@@ -294,12 +296,12 @@ const extendTimelineMarqueeSelection = ({ currentSelection, marqueeSelection, })
294
296
  exports.extendTimelineMarqueeSelection = extendTimelineMarqueeSelection;
295
297
  const defaultTimelineSelectionContextValue = {
296
298
  canSelect: false,
299
+ revealRequest: null,
297
300
  selectedItems: [],
298
301
  isSelected: () => false,
299
302
  selectItem: () => undefined,
300
303
  selectItems: () => undefined,
301
304
  registerMarqueeSelectableItem: () => () => undefined,
302
- registerFocusableItem: () => () => undefined,
303
305
  getMarqueeSelection: () => ({
304
306
  lockedSelectionKind: null,
305
307
  selectedItems: [],
@@ -317,7 +319,6 @@ const TimelineSelectionOrderProvider = ({ children, items }) => {
317
319
  };
318
320
  exports.TimelineSelectionOrderProvider = TimelineSelectionOrderProvider;
319
321
  const CurrentTimelineSelectionContext = (0, react_1.createContext)(null);
320
- const TIMELINE_SELECTION_REVEAL_RETRY_COUNT = 2;
321
322
  const parseEffectIndex = (effectIndex) => {
322
323
  const parsed = Number(effectIndex);
323
324
  if (!Number.isInteger(parsed) || parsed < 0) {
@@ -644,13 +645,12 @@ const TimelineSelectionProvider = ({ children }) => {
644
645
  const canSelect = (0, interactivity_enabled_1.isStudioSelectionEnabled)() &&
645
646
  (previewServerState.type === 'connected' ||
646
647
  window.remotion_isReadOnlyStudio);
648
+ const keyframeOperationsAvailable = (0, browser_studio_operations_1.canUseKeyframeOperations)();
647
649
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
648
650
  const selectionAnchor = (0, react_1.useRef)(null);
649
651
  const selectionScope = (0, react_1.useRef)(null);
650
652
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
651
653
  const marqueeRegistrationCounter = (0, react_1.useRef)(0);
652
- const focusableItems = (0, react_1.useRef)(new Map());
653
- const focusableRegistrationCounter = (0, react_1.useRef)(0);
654
654
  const [revealRequest, setRevealRequest] = (0, react_1.useState)(null);
655
655
  (0, react_1.useEffect)(() => {
656
656
  if (!canSelect) {
@@ -661,7 +661,9 @@ const TimelineSelectionProvider = ({ children }) => {
661
661
  }
662
662
  }, [canSelect]);
663
663
  const canSelectItem = (0, react_1.useCallback)((item) => canSelect &&
664
- (!window.remotion_isReadOnlyStudio || item.type === 'sequence'), [canSelect]);
664
+ (!window.remotion_isReadOnlyStudio ||
665
+ keyframeOperationsAvailable ||
666
+ item.type === 'sequence'), [canSelect, keyframeOperationsAvailable]);
665
667
  const getCurrentAvailableSelectionState = (0, react_1.useCallback)((currentSelectedItems) => {
666
668
  if (selectionScope.current !== timelineSelectionScope) {
667
669
  return exports.EMPTY_TIMELINE_SELECTION_STATE;
@@ -673,58 +675,11 @@ const TimelineSelectionProvider = ({ children }) => {
673
675
  }, [timelineSelectionScope]);
674
676
  const availableSelectionState = getCurrentAvailableSelectionState(selectedItems);
675
677
  const availableSelectedItems = availableSelectionState.selectedItems;
676
- const revealSelectionKey = (0, react_1.useCallback)((selectedKey) => {
677
- let cancelled = false;
678
- let animationFrame = null;
679
- const reveal = (attempt) => {
680
- var _a;
681
- var _b;
682
- if (cancelled) {
683
- return;
684
- }
685
- const scrollParent = timeline_refs_1.timelineVerticalScroll.current;
686
- const focusableRegistrations = focusableItems.current.get(selectedKey);
687
- const focusableElement = scrollParent && focusableRegistrations
688
- ? [...focusableRegistrations.values()]
689
- .sort((a, b) => a.order - b.order)
690
- .map((registered) => registered.getElement())
691
- .find((element) => element !== null && scrollParent.contains(element))
692
- : null;
693
- const rect = (_b = focusableElement === null || focusableElement === void 0 ? void 0 : focusableElement.getBoundingClientRect()) !== null && _b !== void 0 ? _b : (_a = marqueeSelectableItems.current.get(selectedKey)) === null || _a === void 0 ? void 0 : _a.getRect();
694
- if (!scrollParent || !rect) {
695
- if (attempt < TIMELINE_SELECTION_REVEAL_RETRY_COUNT) {
696
- animationFrame = requestAnimationFrame(() => reveal(attempt + 1));
697
- }
698
- return;
699
- }
700
- const parentRect = scrollParent.getBoundingClientRect();
701
- if (rect.top >= parentRect.top && rect.bottom <= parentRect.bottom) {
702
- return;
703
- }
704
- const elementCenter = rect.top + rect.height / 2;
705
- const parentCenter = parentRect.top + parentRect.height / 2;
706
- scrollParent.scrollTop += elementCenter - parentCenter;
707
- };
708
- animationFrame = requestAnimationFrame(() => reveal(0));
709
- return () => {
710
- cancelled = true;
711
- if (animationFrame !== null) {
712
- cancelAnimationFrame(animationFrame);
713
- }
714
- };
715
- }, []);
716
- (0, react_1.useEffect)(() => {
717
- if (revealRequest === null) {
718
- return;
719
- }
720
- return revealSelectionKey(revealRequest.key);
721
- }, [revealRequest, revealSelectionKey]);
722
678
  const requestRevealSelectionItem = (0, react_1.useCallback)((item) => {
723
- const key = (0, exports.getTimelineSelectionKey)(item);
724
679
  setRevealRequest((previousRequest) => {
725
680
  var _a;
726
681
  return ({
727
- key,
682
+ item,
728
683
  token: ((_a = previousRequest === null || previousRequest === void 0 ? void 0 : previousRequest.token) !== null && _a !== void 0 ? _a : 0) + 1,
729
684
  });
730
685
  });
@@ -832,25 +787,6 @@ const TimelineSelectionProvider = ({ children }) => {
832
787
  marqueeSelectableItems.current.delete(key);
833
788
  };
834
789
  }, []);
835
- const registerFocusableItem = (0, react_1.useCallback)((item, getElement) => {
836
- var _a;
837
- const key = (0, exports.getTimelineSelectionKey)(item);
838
- const registrationOrder = focusableRegistrationCounter.current;
839
- focusableRegistrationCounter.current += 1;
840
- const registrations = (_a = focusableItems.current.get(key)) !== null && _a !== void 0 ? _a : new Map();
841
- registrations.set(registrationOrder, {
842
- getElement,
843
- order: registrationOrder,
844
- });
845
- focusableItems.current.set(key, registrations);
846
- return () => {
847
- const latestRegistrations = focusableItems.current.get(key);
848
- latestRegistrations === null || latestRegistrations === void 0 ? void 0 : latestRegistrations.delete(registrationOrder);
849
- if ((latestRegistrations === null || latestRegistrations === void 0 ? void 0 : latestRegistrations.size) === 0) {
850
- focusableItems.current.delete(key);
851
- }
852
- };
853
- }, []);
854
790
  const getMarqueeSelectionForRect = (0, react_1.useCallback)((marqueeRect, lockedSelectionKind) => {
855
791
  const candidates = [...marqueeSelectableItems.current.values()]
856
792
  .sort((a, b) => a.order - b.order)
@@ -891,23 +827,23 @@ const TimelineSelectionProvider = ({ children }) => {
891
827
  }, [availableSelectedItems]);
892
828
  const value = (0, react_1.useMemo)(() => ({
893
829
  canSelect,
830
+ revealRequest,
894
831
  selectedItems: availableSelectedItems,
895
832
  isSelected,
896
833
  selectItem,
897
834
  selectItems,
898
835
  registerMarqueeSelectableItem,
899
- registerFocusableItem,
900
836
  getMarqueeSelection: getMarqueeSelectionForRect,
901
837
  containsSelection,
902
838
  clearSelection,
903
839
  }), [
904
840
  canSelect,
841
+ revealRequest,
905
842
  availableSelectedItems,
906
843
  isSelected,
907
844
  selectItem,
908
845
  selectItems,
909
846
  registerMarqueeSelectableItem,
910
- registerFocusableItem,
911
847
  getMarqueeSelectionForRect,
912
848
  containsSelection,
913
849
  clearSelection,
@@ -938,6 +874,7 @@ const useTimelineMarqueeSelection = () => {
938
874
  const { isHighestContext } = (0, z_index_1.useZIndex)();
939
875
  const [marqueeRect, setMarqueeRect] = (0, react_1.useState)(null);
940
876
  const onPointerDownCapture = (0, react_1.useCallback)((event) => {
877
+ var _a, _b;
941
878
  if (!isHighestContext) {
942
879
  return;
943
880
  }
@@ -955,15 +892,18 @@ const useTimelineMarqueeSelection = () => {
955
892
  return;
956
893
  }
957
894
  const { currentTarget: target } = event;
895
+ const scrollable = timeline_refs_1.scrollableRef.current;
896
+ const verticalScroll = timeline_refs_1.timelineVerticalScroll.current;
897
+ const initialScrollLeft = (_a = scrollable === null || scrollable === void 0 ? void 0 : scrollable.scrollLeft) !== null && _a !== void 0 ? _a : 0;
898
+ const initialScrollTop = (_b = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.scrollTop) !== null && _b !== void 0 ? _b : 0;
958
899
  const initialBounds = target.getBoundingClientRect();
959
- const marqueeBounds = {
960
- bottom: initialBounds.bottom,
961
- left: initialBounds.left,
962
- right: initialBounds.right,
963
- top: initialBounds.top,
964
- };
965
900
  const start = (0, exports.getClampedTimelineMarqueePoint)({
966
- bounds: marqueeBounds,
901
+ bounds: {
902
+ bottom: initialBounds.bottom,
903
+ left: initialBounds.left,
904
+ right: initialBounds.right,
905
+ top: initialBounds.top,
906
+ },
967
907
  x: event.clientX,
968
908
  y: event.clientY,
969
909
  });
@@ -975,34 +915,64 @@ const useTimelineMarqueeSelection = () => {
975
915
  document.body.style.webkitUserSelect = 'none';
976
916
  let hasDragged = false;
977
917
  let lockedSelectionKind = null;
918
+ let lastClientX = event.clientX;
919
+ let lastClientY = event.clientY;
978
920
  const extendSelection = event.metaKey || event.ctrlKey;
979
921
  const selectionBeforeMarquee = selectedItems;
980
- const cleanup = () => {
981
- document.body.style.userSelect = previousUserSelect;
982
- document.body.style.webkitUserSelect = previousWebkitUserSelect;
983
- setMarqueeRect(null);
984
- };
985
922
  const updateSelection = (clientX, clientY) => {
923
+ var _a, _b, _c;
924
+ lastClientX = clientX;
925
+ lastClientY = clientY;
926
+ // The container moves when the timeline scrolls vertically, so read
927
+ // the bounds live. Restrict them to the visible viewport of the
928
+ // vertical scroller so the fixed-positioned marquee cannot paint
929
+ // outside the visible timeline area.
930
+ const liveBounds = target.getBoundingClientRect();
931
+ const verticalRect = (_a = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.getBoundingClientRect()) !== null && _a !== void 0 ? _a : null;
932
+ const bounds = {
933
+ bottom: verticalRect === null
934
+ ? liveBounds.bottom
935
+ : Math.min(liveBounds.bottom, verticalRect.bottom),
936
+ left: liveBounds.left,
937
+ right: liveBounds.right,
938
+ top: verticalRect === null
939
+ ? liveBounds.top
940
+ : Math.max(liveBounds.top, verticalRect.top),
941
+ };
942
+ // The anchor is fixed to timeline content, not to the screen:
943
+ // compensate for any scrolling that happened since pointerdown so the
944
+ // marquee keeps covering the originally spanned content while
945
+ // edge auto-scrolling. It is deliberately not clamped to the bounds -
946
+ // it may sit outside the viewport, and the selection should still
947
+ // include everything between it and the pointer.
948
+ const scrollDeltaX = ((_b = scrollable === null || scrollable === void 0 ? void 0 : scrollable.scrollLeft) !== null && _b !== void 0 ? _b : 0) - initialScrollLeft;
949
+ const scrollDeltaY = ((_c = verticalScroll === null || verticalScroll === void 0 ? void 0 : verticalScroll.scrollTop) !== null && _c !== void 0 ? _c : 0) - initialScrollTop;
950
+ const anchorX = startX - scrollDeltaX;
951
+ const anchorY = startY - scrollDeltaY;
986
952
  const current = (0, exports.getClampedTimelineMarqueePoint)({
987
- bounds: marqueeBounds,
953
+ bounds,
988
954
  x: clientX,
989
955
  y: clientY,
990
956
  });
991
957
  if (!hasDragged &&
992
- Math.max(Math.abs(current.x - startX), Math.abs(current.y - startY)) <
993
- 3) {
958
+ Math.max(Math.abs(current.x - anchorX), Math.abs(current.y - anchorY)) < 3) {
994
959
  return;
995
960
  }
996
961
  hasDragged = true;
997
962
  const rect = (0, exports.getNormalizedTimelineMarqueeRect)({
998
963
  currentX: current.x,
999
964
  currentY: current.y,
1000
- startX,
1001
- startY,
965
+ startX: anchorX,
966
+ startY: anchorY,
1002
967
  });
1003
968
  const nextSelection = getMarqueeSelection(rect, lockedSelectionKind);
1004
969
  lockedSelectionKind = nextSelection.lockedSelectionKind;
1005
- setMarqueeRect(rect);
970
+ setMarqueeRect({
971
+ bottom: Math.min(rect.bottom, bounds.bottom),
972
+ left: Math.max(rect.left, bounds.left),
973
+ right: Math.min(rect.right, bounds.right),
974
+ top: Math.max(rect.top, bounds.top),
975
+ });
1006
976
  selectItems(extendSelection
1007
977
  ? (0, exports.extendTimelineMarqueeSelection)({
1008
978
  currentSelection: selectionBeforeMarquee,
@@ -1010,8 +980,35 @@ const useTimelineMarqueeSelection = () => {
1010
980
  })
1011
981
  : nextSelection.selectedItems);
1012
982
  };
983
+ const autoScroll = (0, timeline_scroll_logic_1.startTimelineEdgeAutoScroll)({
984
+ includeVertical: true,
985
+ onTick: (directions) => {
986
+ if (scrollable && directions.x !== null) {
987
+ scrollable.scrollLeft +=
988
+ directions.x === 'left' ? -timeline_scroll_logic_1.SCROLL_INCREMENT : timeline_scroll_logic_1.SCROLL_INCREMENT;
989
+ }
990
+ if (verticalScroll && directions.y !== null) {
991
+ verticalScroll.scrollTop +=
992
+ directions.y === 'up'
993
+ ? -timeline_scroll_logic_1.EDGE_SCROLL_VERTICAL_INCREMENT
994
+ : timeline_scroll_logic_1.EDGE_SCROLL_VERTICAL_INCREMENT;
995
+ }
996
+ updateSelection(lastClientX, lastClientY);
997
+ },
998
+ });
999
+ const cleanup = () => {
1000
+ autoScroll.stop();
1001
+ document.body.style.userSelect = previousUserSelect;
1002
+ document.body.style.webkitUserSelect = previousWebkitUserSelect;
1003
+ setMarqueeRect(null);
1004
+ };
1013
1005
  const onPointerMove = (moveEvent) => {
1014
1006
  updateSelection(moveEvent.clientX, moveEvent.clientY);
1007
+ // Only auto-scroll for an actual marquee drag, not a plain click
1008
+ // near an edge
1009
+ if (hasDragged) {
1010
+ autoScroll.update(moveEvent);
1011
+ }
1015
1012
  };
1016
1013
  (0, pointer_session_1.startCapturedPointerSession)({
1017
1014
  event,
@@ -1049,16 +1046,6 @@ const useTimelineMarqueeSelectableItem = (item, ref) => {
1049
1046
  }, [item, ref, registerMarqueeSelectableItem]);
1050
1047
  };
1051
1048
  exports.useTimelineMarqueeSelectableItem = useTimelineMarqueeSelectableItem;
1052
- const useTimelineFocusableItem = (item, ref) => {
1053
- const { registerFocusableItem } = (0, exports.useTimelineSelection)();
1054
- (0, react_1.useEffect)(() => {
1055
- if (item === null) {
1056
- return;
1057
- }
1058
- return registerFocusableItem(item, () => ref.current);
1059
- }, [item, ref, registerFocusableItem]);
1060
- };
1061
- exports.useTimelineFocusableItem = useTimelineFocusableItem;
1062
1049
  const useTimelineRowSelection = (nodePathInfo) => {
1063
1050
  const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
1064
1051
  const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);