@remotion/studio 4.0.525 → 4.0.527

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 (195) hide show
  1. package/dist/api/focus-default-props-path.js +7 -1
  2. package/dist/api/restart-studio.d.ts +1 -1
  3. package/dist/api/restart-studio.js +1 -1
  4. package/dist/components/AgentPrompt.d.ts +6 -0
  5. package/dist/components/AgentPrompt.js +107 -0
  6. package/dist/components/AssetFileIcon.js +2 -0
  7. package/dist/components/AssetSelectorItem.d.ts +1 -23
  8. package/dist/components/AssetSelectorItem.js +10 -200
  9. package/dist/components/Canvas.js +109 -44
  10. package/dist/components/CanvasCaptureDropHandler.js +63 -0
  11. package/dist/components/CanvasOrLoading.js +10 -2
  12. package/dist/components/CaptionInspector.js +9 -3
  13. package/dist/{error-overlay/remotion-overlay → components}/CodeFrame.d.ts +2 -0
  14. package/dist/components/CodeFrame.js +77 -0
  15. package/dist/components/CompositionSelectorItem.js +7 -17
  16. package/dist/components/CurrentAsset.js +6 -4
  17. package/dist/components/ElementInstallConfirmation.js +69 -38
  18. package/dist/components/FilePreview.js +4 -0
  19. package/dist/components/FixComputedValueModal.js +64 -96
  20. package/dist/components/GenerateWithAgentModal.d.ts +9 -0
  21. package/dist/components/GenerateWithAgentModal.js +39 -0
  22. package/dist/components/InitialCompositionLoader.js +1 -1
  23. package/dist/components/InlineDropdown.js +26 -2
  24. package/dist/components/InlineEditableTitle.js +3 -0
  25. package/dist/components/InspectorOpenInEditor.js +8 -4
  26. package/dist/components/InspectorPanel/CollapsibleInspectorSection.d.ts +7 -0
  27. package/dist/components/InspectorPanel/CollapsibleInspectorSection.js +14 -0
  28. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.d.ts +1 -1
  29. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +20 -8
  30. package/dist/components/InspectorPanel/CompositionInspector.js +32 -15
  31. package/dist/components/InspectorPanel/CompositionMetadata.js +7 -0
  32. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +6 -12
  33. package/dist/components/InspectorPanel/ElementLibraryButton.js +2 -0
  34. package/dist/components/InspectorPanel/GuideInspector.js +2 -3
  35. package/dist/components/InspectorPanel/KeyframeSettings.js +5 -6
  36. package/dist/components/InspectorPanel/MultiSequenceInspector.js +34 -2
  37. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +45 -4
  38. package/dist/components/InspectorPanel/common.d.ts +4 -0
  39. package/dist/components/InspectorPanel/common.js +15 -2
  40. package/dist/components/InspectorPanel/styles.d.ts +0 -3
  41. package/dist/components/InspectorPanel/styles.js +3 -27
  42. package/dist/components/InspectorPanel/use-composition-actions.d.ts +2 -0
  43. package/dist/components/InspectorPanel/use-composition-actions.js +16 -0
  44. package/dist/components/InspectorPanel/use-inspector-section-expanded.d.ts +1 -0
  45. package/dist/components/InspectorPanel/use-inspector-section-expanded.js +21 -0
  46. package/dist/components/InspectorSequenceSection.js +44 -35
  47. package/dist/components/InspectorSourceLocation.js +4 -0
  48. package/dist/components/KeyboardShortcutsSettings.js +12 -4
  49. package/dist/components/LutPreview.d.ts +4 -0
  50. package/dist/components/LutPreview.js +192 -0
  51. package/dist/components/MenuBuildIndicator.js +1 -0
  52. package/dist/components/MenuCompositionName.js +4 -9
  53. package/dist/components/Modals.js +3 -6
  54. package/dist/components/ModelsSettings.js +15 -4
  55. package/dist/components/NewComposition/CancelButton.js +1 -1
  56. package/dist/components/Notifications/NotificationCenter.d.ts +0 -1
  57. package/dist/components/Notifications/NotificationCenter.js +1 -22
  58. package/dist/components/Preview.js +3 -0
  59. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +1 -0
  60. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -0
  61. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +4 -9
  62. package/dist/components/RadioButton.js +1 -0
  63. package/dist/components/RenderModal/DataEditor.js +4 -1
  64. package/dist/components/RenderModal/SchemaEditor/scroll-to-default-props-path.d.ts +1 -0
  65. package/dist/components/RenderModal/SchemaEditor/scroll-to-default-props-path.js +2 -1
  66. package/dist/components/RenderModal/WebRenderModal.js +10 -2
  67. package/dist/components/RenderQueue/CaptionQueueItem.js +5 -2
  68. package/dist/components/RenderQueue/CaptionQueueProcessor.js +35 -8
  69. package/dist/components/RenderQueue/VideoMattingQueueItem.js +1 -0
  70. package/dist/components/RenderQueue/caption-job-types.d.ts +6 -0
  71. package/dist/components/RenderQueue/index.js +1 -0
  72. package/dist/components/RendersTab.js +4 -0
  73. package/dist/components/SelectedOutlineElement.js +6 -0
  74. package/dist/components/SelectedOutlineSnapIndicators.d.ts +6 -0
  75. package/dist/components/SelectedOutlineSnapIndicators.js +16 -12
  76. package/dist/components/SequencePropsSubscriptionProvider.d.ts +3 -0
  77. package/dist/components/SequencePropsSubscriptionProvider.js +8 -6
  78. package/dist/components/SettingsButton.js +11 -2
  79. package/dist/components/SettingsModal.d.ts +1 -2
  80. package/dist/components/SettingsModal.js +24 -6
  81. package/dist/components/SettingsModalFooter.js +17 -3
  82. package/dist/components/SkillsSettings.d.ts +5 -0
  83. package/dist/components/SkillsSettings.js +29 -26
  84. package/dist/components/Timeline/Timeline.js +10 -11
  85. package/dist/components/Timeline/TimelineAssetField.js +81 -51
  86. package/dist/components/Timeline/TimelineDeleteKeybindings.js +6 -9
  87. package/dist/components/Timeline/TimelineEffectItem.js +1 -0
  88. package/dist/components/Timeline/TimelineExpandArrowButton.js +1 -0
  89. package/dist/components/Timeline/TimelineExpandedRow.js +1 -0
  90. package/dist/components/Timeline/TimelineFieldLabel.js +1 -0
  91. package/dist/components/Timeline/TimelineHeightContainer.js +11 -1
  92. package/dist/components/Timeline/TimelineKeyframeControls.js +16 -1
  93. package/dist/components/Timeline/TimelineLayerChildren.d.ts +3 -3
  94. package/dist/components/Timeline/TimelineLayerChildren.js +11 -9
  95. package/dist/components/Timeline/TimelineLayerEye.d.ts +1 -1
  96. package/dist/components/Timeline/TimelineLayerEye.js +6 -3
  97. package/dist/components/Timeline/TimelineList.js +9 -3
  98. package/dist/components/Timeline/TimelineSchemaField.js +2 -6
  99. package/dist/components/Timeline/TimelineSelection.d.ts +14 -3
  100. package/dist/components/Timeline/TimelineSelection.js +91 -49
  101. package/dist/components/Timeline/TimelineSequence.js +28 -2
  102. package/dist/components/Timeline/TimelineSequenceFrame.js +1 -0
  103. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -0
  104. package/dist/components/Timeline/TimelineSequenceItem.js +45 -13
  105. package/dist/components/Timeline/TimelineViewport.d.ts +1 -0
  106. package/dist/components/Timeline/TimelineViewport.js +10 -1
  107. package/dist/components/Timeline/TimelineVirtualization.d.ts +3 -3
  108. package/dist/components/Timeline/delete-selected-timeline-item.js +2 -2
  109. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -2
  110. package/dist/components/Timeline/get-sequence-context-menu-items.js +143 -46
  111. package/dist/components/Timeline/normalize-font-weight-for-keyframe.d.ts +1 -0
  112. package/dist/components/Timeline/normalize-font-weight-for-keyframe.js +19 -0
  113. package/dist/components/Timeline/split-selected-timeline-item.d.ts +13 -10
  114. package/dist/components/Timeline/split-selected-timeline-item.js +58 -35
  115. package/dist/components/Timeline/timeline-display-groups.d.ts +9 -0
  116. package/dist/components/Timeline/timeline-display-groups.js +66 -0
  117. package/dist/components/Timeline/use-timeline-asset-drop.js +21 -21
  118. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  119. package/dist/components/Timeline/use-timeline-expanded-tree.js +1 -2
  120. package/dist/components/TimelineCombobox.js +1 -0
  121. package/dist/components/Transcription/TranscriptionModal.js +16 -11
  122. package/dist/components/Transcription/TranscriptionModalWithOptionalWhisper.js +1 -1
  123. package/dist/components/UpdateStatusContext.d.ts +2 -2
  124. package/dist/components/UpdateStatusContext.js +6 -7
  125. package/dist/components/UpdatesSettings.js +6 -6
  126. package/dist/components/WebMcp.js +41 -41
  127. package/dist/components/asset-context-menu.d.ts +32 -0
  128. package/dist/components/asset-context-menu.js +242 -0
  129. package/dist/components/composition-drop-preview.d.ts +9 -2
  130. package/dist/components/composition-drop-preview.js +7 -4
  131. package/dist/components/composition-menu-items.d.ts +4 -6
  132. package/dist/components/composition-menu-items.js +191 -75
  133. package/dist/components/delete-jsx-nodes-api.d.ts +2 -0
  134. package/dist/components/{delete-jsx-node-api.js → delete-jsx-nodes-api.js} +5 -5
  135. package/dist/components/get-open-in-menu-items.d.ts +6 -5
  136. package/dist/components/get-open-in-menu-items.js +22 -16
  137. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  138. package/dist/components/keyboard-shortcuts.js +3 -1
  139. package/dist/components/public-output-name.d.ts +1 -0
  140. package/dist/components/public-output-name.js +7 -3
  141. package/dist/components/selected-outline-order.js +18 -12
  142. package/dist/components/use-open-in-menu-apps.d.ts +14 -0
  143. package/dist/components/use-open-in-menu-apps.js +33 -0
  144. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +2 -2
  145. package/dist/error-overlay/remotion-overlay/OpenInEditor.d.ts +1 -0
  146. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +3 -3
  147. package/dist/error-overlay/remotion-overlay/StackFrame.d.ts +5 -1
  148. package/dist/error-overlay/remotion-overlay/StackFrame.js +26 -19
  149. package/dist/esm/{CaptionQueueProcessor-k0yrm3dj.mjs → CaptionQueueProcessor-npa6szn1.mjs} +39 -8
  150. package/dist/esm/{LazyModels-gfmpcy4h.mjs → LazyModels-nh3c8h9p.mjs} +4 -3
  151. package/dist/esm/{LazyModels-m1rf06wh.mjs → LazyModels-rr5v8h5y.mjs} +4 -3
  152. package/dist/esm/{TranscriptionModal-8pvrehg4.mjs → TranscriptionModal-79m5wgcj.mjs} +25 -17
  153. package/dist/esm/{VideoMattingModal-fefbzgka.mjs → VideoMattingModal-31pew0xj.mjs} +9 -6
  154. package/dist/esm/index-21hxsfaa.mjs +239 -0
  155. package/dist/esm/{index-s848rffx.mjs → index-4zen9prq.mjs} +5438 -4686
  156. package/dist/esm/index-5t2dwxsk.mjs +530 -0
  157. package/dist/esm/{index-vsxrxfpj.mjs → index-614tdz2q.mjs} +1 -1
  158. package/dist/esm/{index-0x13f28h.mjs → index-9xxg6218.mjs} +20 -541
  159. package/dist/esm/{index-hbezgbbq.mjs → index-ac5550e7.mjs} +1 -1
  160. package/dist/esm/{index-41kqns5c.mjs → index-e855w59j.mjs} +15 -92
  161. package/dist/esm/{index-tzxb8808.mjs → index-n5gmcvhz.mjs} +8 -8
  162. package/dist/esm/{index-ggqpre9v.mjs → index-ppspzgn9.mjs} +4963 -4178
  163. package/dist/esm/{index-jrw61pkj.mjs → index-r0ejh5sy.mjs} +1 -1
  164. package/dist/esm/index-r1gr3j3a.mjs +80 -0
  165. package/dist/esm/{index-mww32xc8.mjs → index-s7qa3xbw.mjs} +6 -4
  166. package/dist/esm/{index-1089795y.mjs → index-vxwg66ar.mjs} +7 -22
  167. package/dist/esm/index.mjs +13 -6
  168. package/dist/esm/internals.mjs +10 -7
  169. package/dist/esm/previewEntry.mjs +10 -7
  170. package/dist/esm/{resolve-composition-component-location-bt2d6qxq.mjs → resolve-composition-component-location-qrp05g62.mjs} +1 -1
  171. package/dist/helpers/client-id.d.ts +1 -0
  172. package/dist/helpers/client-id.js +8 -4
  173. package/dist/helpers/copy-text.js +1 -16
  174. package/dist/helpers/cube-lut.d.ts +12 -0
  175. package/dist/helpers/cube-lut.js +160 -0
  176. package/dist/helpers/get-preview-file-type.d.ts +1 -1
  177. package/dist/helpers/get-preview-file-type.js +3 -0
  178. package/dist/helpers/hoverable.js +2 -1
  179. package/dist/helpers/open-in-editor.d.ts +5 -2
  180. package/dist/helpers/open-in-editor.js +13 -5
  181. package/dist/helpers/settings-tab-availability.d.ts +14 -0
  182. package/dist/helpers/settings-tab-availability.js +35 -0
  183. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  184. package/dist/helpers/use-keybinding.d.ts +1 -1
  185. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  186. package/dist/helpers/use-menu-structure.js +31 -21
  187. package/dist/icons/lut.d.ts +4 -0
  188. package/dist/icons/lut.js +6 -0
  189. package/dist/icons/sparkles.d.ts +4 -0
  190. package/dist/icons/sparkles.js +6 -0
  191. package/dist/state/modals.d.ts +17 -2
  192. package/dist/state/timeline-zoom.js +4 -0
  193. package/package.json +19 -19
  194. package/dist/components/delete-jsx-node-api.d.ts +0 -2
  195. package/dist/error-overlay/remotion-overlay/CodeFrame.js +0 -62
@@ -6,6 +6,7 @@ const remotion_1 = require("remotion");
6
6
  const client_id_1 = require("../../helpers/client-id");
7
7
  const use_keybinding_1 = require("../../helpers/use-keybinding");
8
8
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
9
+ const SequencePropsSubscriptionProvider_1 = require("../SequencePropsSubscriptionProvider");
9
10
  const duplicate_selected_timeline_item_1 = require("./duplicate-selected-timeline-item");
10
11
  const imperative_state_1 = require("./imperative-state");
11
12
  const split_selected_timeline_item_1 = require("./split-selected-timeline-item");
@@ -15,7 +16,7 @@ const TimelineDeleteKeybindings = () => {
15
16
  const keybindings = (0, use_keybinding_1.useKeybinding)();
16
17
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
17
18
  const sequencesRef = (0, react_1.useContext)(remotion_1.Internals.SequenceManagerRefContext);
18
- const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
19
+ const overrideIdToNodePathMappingsRef = (0, react_1.useContext)(SequencePropsSubscriptionProvider_1.OverrideIdToNodePathMappingsRefContext);
19
20
  const propStatusesRef = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesRefContext);
20
21
  const { canSelect } = (0, TimelineSelection_1.useTimelineSelection)();
21
22
  const currentSelection = (0, TimelineSelection_1.useCurrentTimelineSelectionStateAsRef)();
@@ -56,11 +57,8 @@ const TimelineDeleteKeybindings = () => {
56
57
  });
57
58
  const split = keybindings.registerKeybinding({
58
59
  event: 'keydown',
59
- key: 'd',
60
- callback: (event) => {
61
- if (!(0, split_selected_timeline_item_1.shouldHandleTimelineSplitShortcut)(event)) {
62
- return;
63
- }
60
+ action: 'splitSequences',
61
+ callback: () => {
64
62
  const { selectedItems } = currentSelection.current;
65
63
  if (selectedItems.length === 0) {
66
64
  return;
@@ -68,7 +66,7 @@ const TimelineDeleteKeybindings = () => {
68
66
  const splitPromise = (0, split_selected_timeline_item_1.splitSelectedTimelineItems)({
69
67
  selections: selectedItems,
70
68
  sequences: sequencesRef.current,
71
- overrideIdsToNodePaths: overrideIdToNodePathMappings,
69
+ overrideIdsToNodePaths: overrideIdToNodePathMappingsRef.current,
72
70
  propStatuses: propStatusesRef.current,
73
71
  splitFrame: (0, imperative_state_1.getCurrentFrame)(),
74
72
  });
@@ -77,7 +75,6 @@ const TimelineDeleteKeybindings = () => {
77
75
  }
78
76
  splitPromise.catch(() => undefined);
79
77
  },
80
- commandCtrlKey: true,
81
78
  preventDefault: true,
82
79
  triggerIfInputFieldFocused: false,
83
80
  keepRegisteredWhenNotHighestContext: false,
@@ -93,7 +90,7 @@ const TimelineDeleteKeybindings = () => {
93
90
  currentSelection,
94
91
  deleteTimelineItems,
95
92
  keybindings,
96
- overrideIdToNodePathMappings,
93
+ overrideIdToNodePathMappingsRef,
97
94
  propStatusesRef,
98
95
  previewServerState,
99
96
  sequencesRef,
@@ -24,6 +24,7 @@ const rowLabel = {
24
24
  fontSize: 12,
25
25
  color: colors_1.WHITE_ALPHA_80,
26
26
  userSelect: 'none',
27
+ WebkitUserSelect: 'none',
27
28
  };
28
29
  const rowStyle = {
29
30
  height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
@@ -52,6 +52,7 @@ const arrowButton = {
52
52
  fontSize: 8,
53
53
  marginRight: 4,
54
54
  userSelect: 'none',
55
+ WebkitUserSelect: 'none',
55
56
  outline: 'none',
56
57
  lineHeight: 1,
57
58
  };
@@ -20,6 +20,7 @@ const rowLabel = {
20
20
  fontSize: 12,
21
21
  color: colors_1.WHITE_ALPHA_80,
22
22
  userSelect: 'none',
23
+ WebkitUserSelect: 'none',
23
24
  };
24
25
  const TimelineExpandedRowInner = ({ node, depth, nestedDepth, rowDepthBase, getIsExpanded, toggleTrack, validatedLocation, nodePath, schema, keyframeDisplayOffset, keyframeControlsMode, }) => {
25
26
  const rowDepth = (rowDepthBase !== null && rowDepthBase !== void 0 ? rowDepthBase : (0, timeline_row_layout_1.getExpandedRowDepth)({ nestedDepth, treeDepth: 0 })) + depth;
@@ -12,6 +12,7 @@ const fieldNameBase = {
12
12
  lineHeight: `${timeline_field_row_layout_1.TIMELINE_STACKED_FIELD_HEADER_HEIGHT}px`,
13
13
  color: colors_1.WHITE_ALPHA_80,
14
14
  userSelect: 'none',
15
+ WebkitUserSelect: 'none',
15
16
  whiteSpace: 'nowrap',
16
17
  overflow: 'hidden',
17
18
  textOverflow: 'ellipsis',
@@ -47,7 +47,17 @@ const baseStyle = {
47
47
  };
48
48
  const TimelineHeightContainerInner = ({ children }) => {
49
49
  const { totalSize } = (0, TimelineVirtualization_1.useTimelineVirtualization)();
50
+ const onPointerDownCapture = (0, react_1.useCallback)((event) => {
51
+ const { activeElement } = document;
52
+ if (event.button === 0 &&
53
+ activeElement instanceof HTMLButtonElement &&
54
+ event.target instanceof Node &&
55
+ !activeElement.contains(event.target)) {
56
+ // Timeline drags can prevent the browser's default focus change.
57
+ activeElement.blur();
58
+ }
59
+ }, []);
50
60
  const style = (0, react_1.useMemo)(() => ({ ...baseStyle, height: totalSize }), [totalSize]);
51
- return jsx_runtime_1.jsx("div", { style: style, children: children });
61
+ return (jsx_runtime_1.jsx("div", { style: style, onPointerDownCapture: onPointerDownCapture, children: children }));
52
62
  };
53
63
  exports.TimelineHeightContainer = react_1.default.memo(TimelineHeightContainerInner);
@@ -10,11 +10,13 @@ const client_id_1 = require("../../helpers/client-id");
10
10
  const colors_1 = require("../../helpers/colors");
11
11
  const timeline_layout_1 = require("../../helpers/timeline-layout");
12
12
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
13
+ const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
13
14
  const call_add_keyframe_1 = require("./call-add-keyframe");
14
15
  const call_delete_keyframe_1 = require("./call-delete-keyframe");
15
16
  const get_easing_selection_after_keyframe_delete_1 = require("./get-easing-selection-after-keyframe-delete");
16
17
  const get_keyframe_navigation_1 = require("./get-keyframe-navigation");
17
18
  const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
19
+ const normalize_font_weight_for_keyframe_1 = require("./normalize-font-weight-for-keyframe");
18
20
  const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
19
21
  const TimelineKeyframeDiamondIcon_1 = require("./TimelineKeyframeDiamondIcon");
20
22
  const TimelineKeyframeTracksContext_1 = require("./TimelineKeyframeTracksContext");
@@ -50,6 +52,7 @@ const navButtonStyle = {
50
52
  outline: 'none',
51
53
  padding: 0,
52
54
  userSelect: 'none',
55
+ WebkitUserSelect: 'none',
53
56
  width: NAV_BUTTON_SIZE,
54
57
  };
55
58
  const inspectorNavButtonStyle = {
@@ -222,12 +225,19 @@ const getAddChange = (target) => {
222
225
  if (value === null) {
223
226
  return null;
224
227
  }
228
+ const fieldSchema = target.schema[target.fieldKey];
229
+ const normalizedValue = (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'font-weight'
230
+ ? (0, normalize_font_weight_for_keyframe_1.normalizeFontWeightForKeyframe)(value)
231
+ : value;
232
+ if (normalizedValue === null) {
233
+ return null;
234
+ }
225
235
  const change = {
226
236
  fileName: target.fileName,
227
237
  nodePath: target.nodePath,
228
238
  fieldKey: target.fieldKey,
229
239
  sourceFrame: target.sourceFrame,
230
- value,
240
+ value: normalizedValue,
231
241
  schema: target.schema,
232
242
  };
233
243
  if (target.effectIndex === null) {
@@ -313,6 +323,7 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
313
323
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
314
324
  const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
315
325
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
326
+ const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
316
327
  const { selectedItems, selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
317
328
  const tracks = (0, TimelineKeyframeTracksContext_1.useTimelineKeyframeTracks)();
318
329
  const clientId = previewServerState.type === 'connected'
@@ -481,6 +492,9 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
481
492
  setPropStatuses,
482
493
  clientId,
483
494
  });
495
+ for (const { target } of addChanges) {
496
+ expandParentTracks(target.nodePathInfo);
497
+ }
484
498
  if (mode === 'timeline') {
485
499
  selectItems(addChanges.map(({ target }) => ({
486
500
  type: 'keyframe',
@@ -491,6 +505,7 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
491
505
  }, [
492
506
  canToggleKeyframe,
493
507
  clientId,
508
+ expandParentTracks,
494
509
  hasKeyframeAtCurrentFrame,
495
510
  keyframeToggleTargets,
496
511
  mode,
@@ -1,14 +1,14 @@
1
1
  import React from 'react';
2
2
  import type { TSequence } from 'remotion';
3
- import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
3
+ import type { TimelineTrackWithDisplayGroup } from './timeline-display-groups';
4
4
  export declare const TimelineLayerChildrenProvider: React.Provider<{
5
5
  readonly collapsed: Record<string, boolean>;
6
6
  readonly keys: Map<string, string>;
7
7
  readonly parents: Set<string>;
8
8
  readonly toggle: (key: string) => void;
9
9
  } | null>;
10
- export declare const useTimelineLayerChildren: (tracks: TimelineTrackData[], sequences: TSequence[], compositionId: string | null) => {
11
- visibleTracks: TimelineTrackData[];
10
+ export declare const useTimelineLayerChildren: (tracks: TimelineTrackWithDisplayGroup[], sequences: TSequence[], compositionId: string | null) => {
11
+ visibleTracks: TimelineTrackWithDisplayGroup[];
12
12
  value: {
13
13
  collapsed: Record<string, boolean>;
14
14
  keys: Map<string, string>;
@@ -70,17 +70,19 @@ const useTimelineLayerChildren = (tracks, sequences, compositionId) => {
70
70
  parent = (_c = (_a = byId.get(parent)) === null || _a === void 0 ? void 0 : _a.parent) !== null && _c !== void 0 ? _c : null;
71
71
  }
72
72
  ancestors.set(track.sequence.id, parentIds);
73
- // Source identity survives remounts. For layers without source metadata,
74
- // use the structural position instead of the ephemeral sequence ID.
73
+ // Source identity survives remounts. While it is resolving, the stack
74
+ // gives interactive layers a stable display identity.
75
75
  const identity = track.nodePathInfo
76
76
  ? ['source', (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(track.nodePathInfo)]
77
- : [
78
- 'position',
79
- ...[...parentIds]
80
- .reverse()
81
- .concat(track.sequence.id)
82
- .map((id) => siblingIndices.get(id)),
83
- ];
77
+ : track.displayGroup
78
+ ? ['stack', track.displayGroup.key]
79
+ : [
80
+ 'position',
81
+ ...[...parentIds]
82
+ .reverse()
83
+ .concat(track.sequence.id)
84
+ .map((id) => siblingIndices.get(id)),
85
+ ];
84
86
  keys.set(track.sequence.id, JSON.stringify([compositionId, identity]));
85
87
  }
86
88
  return { keys, parents, ancestors };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  export declare const timelineLayerIconContainer: React.CSSProperties;
3
3
  export declare const TimelineLayerEye: React.FC<{
4
- readonly onInvoked: (type: 'enable' | 'disable') => void;
4
+ readonly onInvoked: ((type: 'enable' | 'disable') => void) | null;
5
5
  readonly hidden: boolean;
6
6
  readonly type: 'eye' | 'speaker' | 'effect';
7
7
  }>;
@@ -54,6 +54,9 @@ const TimelineLayerEye = ({ onInvoked, hidden, type }) => {
54
54
  }
55
55
  e.preventDefault();
56
56
  e.stopPropagation();
57
+ if (onInvoked === null) {
58
+ return;
59
+ }
57
60
  stopLayerPointerSession === null || stopLayerPointerSession === void 0 ? void 0 : stopLayerPointerSession();
58
61
  layerPointedDown = hidden ? 'enable' : 'disable';
59
62
  onInvoked(layerPointedDown);
@@ -83,14 +86,14 @@ const TimelineLayerEye = ({ onInvoked, hidden, type }) => {
83
86
  e.stopPropagation();
84
87
  }, []);
85
88
  const onPointerEnter = (0, react_1.useCallback)(() => {
86
- if (layerPointedDown) {
89
+ if (layerPointedDown && onInvoked !== null) {
87
90
  onInvoked(layerPointedDown);
88
91
  }
89
92
  }, [onInvoked]);
90
93
  const registerLayerEye = (0, react_1.useCallback)((element) => {
91
94
  if (element) {
92
95
  layerEyeActions.set(element, () => {
93
- if (layerPointedDown) {
96
+ if (layerPointedDown && onInvoked !== null) {
94
97
  onInvoked(layerPointedDown);
95
98
  }
96
99
  });
@@ -99,7 +102,7 @@ const TimelineLayerEye = ({ onInvoked, hidden, type }) => {
99
102
  const onDoubleClick = (0, react_1.useCallback)((e) => {
100
103
  e.stopPropagation();
101
104
  }, []);
102
- return (jsx_runtime_1.jsx("div", { ref: registerLayerEye, [TIMELINE_LAYER_EYE_ATTR]: true, style: exports.timelineLayerIconContainer, draggable: false, onDragStart: onDragStart, onDoubleClick: onDoubleClick, onPointerEnter: onPointerEnter, onPointerDown: onPointerDown, children: renderAction(colors_1.LIGHT_COLOR) }));
105
+ return (jsx_runtime_1.jsx("div", { ref: registerLayerEye, [TIMELINE_LAYER_EYE_ATTR]: true, style: exports.timelineLayerIconContainer, draggable: false, onDragStart: onDragStart, onDoubleClick: onDoubleClick, onPointerEnter: onInvoked === null ? undefined : onPointerEnter, onPointerDown: onPointerDown, children: renderAction(colors_1.LIGHT_COLOR) }));
103
106
  };
104
107
  exports.TimelineLayerEye = TimelineLayerEye;
105
108
  const spacerStyle = {
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.TimelineList = void 0;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
5
9
  const colors_1 = require("../../helpers/colors");
6
10
  const TimelineSequenceItem_1 = require("./TimelineSequenceItem");
7
11
  const TimelineVirtualization_1 = require("./TimelineVirtualization");
@@ -10,11 +14,13 @@ const container = {
10
14
  background: colors_1.BACKGROUND,
11
15
  position: 'relative',
12
16
  };
13
- const TimelineListTrack = ({ row }) => {
17
+ const noConnectedCompositions = [];
18
+ const TimelineListTrack = react_1.default.memo(({ row }) => {
14
19
  var _a;
20
+ var _b, _c;
15
21
  const { afterDropLineOffset, siblingIndex, track } = row;
16
- return (jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { afterDropLineOffset: afterDropLineOffset, siblingIndex: siblingIndex, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset }));
17
- };
22
+ return (jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { afterDropLineOffset: afterDropLineOffset, siblingIndex: siblingIndex, connectedCompositions: (_b = track.connectedCompositions) !== null && _b !== void 0 ? _b : noConnectedCompositions, nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset, numberOfHiddenDuplicates: Math.max(0, ((_c = (_a = track.displayGroup) === null || _a === void 0 ? void 0 : _a.numberOfSequences) !== null && _c !== void 0 ? _c : 1) - 1), showProvisionalVisibilityToggle: track.nodePathInfo === null && track.displayGroup !== null }));
23
+ });
18
24
  const TimelineList = () => {
19
25
  const { rows, tracksEnd, virtualItems } = (0, TimelineVirtualization_1.useTimelineVirtualization)();
20
26
  return (jsx_runtime_1.jsx("div", { style: { ...container, height: tracksEnd }, children: virtualItems.map((virtualItem) => (jsx_runtime_1.jsx("div", { style: {
@@ -39,7 +39,6 @@ const react_1 = __importStar(require("react"));
39
39
  const colors_1 = require("../../helpers/colors");
40
40
  const hoverable_1 = require("../../helpers/hoverable");
41
41
  const modals_1 = require("../../state/modals");
42
- const SettingsContext_1 = require("../SettingsContext");
43
42
  const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
44
43
  const TimelineArrayField_1 = require("./TimelineArrayField");
45
44
  const TimelinePrimitiveFieldValue_1 = require("./TimelinePrimitiveFieldValue");
@@ -117,16 +116,13 @@ const UnsupportedStatus = ({ label, onFix, formattedValue }) => {
117
116
  exports.UnsupportedStatus = UnsupportedStatus;
118
117
  const TimelineNonEditableStatus = ({ propStatus, field, runtimeValue, validatedLocation }) => {
119
118
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
120
- const { remotionSkillsInfo } = (0, SettingsContext_1.useSettings)();
121
119
  const onFix = (0, react_1.useCallback)(() => {
122
- var _a;
123
120
  setSelectedModal({
124
121
  type: 'fix-computed-value',
125
122
  prop: field.key,
126
- context: `${validatedLocation.source}:${validatedLocation.line}:${validatedLocation.column}`,
127
- remotionInteractivitySkillAvailable: (_a = remotionSkillsInfo === null || remotionSkillsInfo === void 0 ? void 0 : remotionSkillsInfo.remotionInteractivitySkillAvailable) !== null && _a !== void 0 ? _a : false,
123
+ location: validatedLocation,
128
124
  });
129
- }, [field.key, remotionSkillsInfo, setSelectedModal, validatedLocation]);
125
+ }, [field.key, setSelectedModal, validatedLocation]);
130
126
  if (propStatus.status === 'computed') {
131
127
  return (jsx_runtime_1.jsx(exports.UnsupportedStatus, { label: runtimeValue === undefined
132
128
  ? 'computed'
@@ -155,14 +155,20 @@ export declare const useTimelineMarqueeSelection: () => {
155
155
  };
156
156
  export declare const useTimelineMarqueeSelectableItem: (item: CanvasSelectionItem | null, ref: React.RefObject<Element | null>) => void;
157
157
  export declare const useTimelineRowSelection: (nodePathInfo: SequenceNodePathInfo | null, revealInInspector?: boolean) => {
158
+ clearSelection: () => void;
158
159
  onSelect: (interaction?: CanvasSelectionInteraction | undefined) => void;
159
160
  selectable: boolean;
161
+ selectedItems: readonly CanvasSelectionItem[];
162
+ selectItem: (item: CanvasSelectionItem, interaction?: CanvasSelectionInteraction | undefined, allSelectableItems?: readonly CanvasSelectionItem[] | undefined, options?: TimelineSelectionOptions | undefined) => void;
160
163
  selectionItem: CanvasSelectionItem | null;
161
164
  selected: boolean;
162
165
  };
163
166
  export declare const useTimelineKeyframeSelection: (nodePathInfo: SequenceNodePathInfo, frame: number) => {
167
+ clearSelection: () => void;
164
168
  onSelect: (interaction?: CanvasSelectionInteraction | undefined) => void;
165
169
  selectable: boolean;
170
+ selectedItems: readonly CanvasSelectionItem[];
171
+ selectItem: (item: CanvasSelectionItem, interaction?: CanvasSelectionInteraction | undefined, allSelectableItems?: readonly CanvasSelectionItem[] | undefined, options?: TimelineSelectionOptions | undefined) => void;
166
172
  selectionItem: CanvasSelectionItem;
167
173
  selected: boolean;
168
174
  };
@@ -172,9 +178,11 @@ export declare const useTimelineEasingSelection: ({ nodePathInfo, fromFrame, toF
172
178
  readonly toFrame: number;
173
179
  readonly segmentIndex: number;
174
180
  }) => {
181
+ clearSelection: () => void;
175
182
  onSelect: (interaction?: CanvasSelectionInteraction | undefined) => void;
176
183
  selectable: boolean;
177
- selected: boolean;
184
+ selectedItems: readonly CanvasSelectionItem[];
185
+ selectItem: (item: CanvasSelectionItem, interaction?: CanvasSelectionInteraction | undefined, allSelectableItems?: readonly CanvasSelectionItem[] | undefined, options?: TimelineSelectionOptions | undefined) => void;
178
186
  selectionItem: {
179
187
  readonly type: "easing";
180
188
  readonly nodePathInfo: SequenceNodePathInfo;
@@ -182,13 +190,16 @@ export declare const useTimelineEasingSelection: ({ nodePathInfo, fromFrame, toF
182
190
  readonly toFrame: number;
183
191
  readonly segmentIndex: number;
184
192
  };
193
+ selected: boolean;
185
194
  };
186
195
  export declare const useTimelineGuideSelection: (guideId: string) => {
187
196
  clearSelection: () => void;
188
- onSelect: () => void;
197
+ onSelect: (interaction?: CanvasSelectionInteraction | undefined) => void;
189
198
  selectable: boolean;
190
- selected: boolean;
199
+ selectedItems: readonly CanvasSelectionItem[];
200
+ selectItem: (item: CanvasSelectionItem, interaction?: CanvasSelectionInteraction | undefined, allSelectableItems?: readonly CanvasSelectionItem[] | undefined, options?: TimelineSelectionOptions | undefined) => void;
191
201
  selectionItem: CanvasSelectionItem;
202
+ selected: boolean;
192
203
  };
193
204
  export declare const useTimelineRowContainsSelection: (nodePathInfo: SequenceNodePathInfo | null) => boolean;
194
205
  export declare const useTimelineRowHighlightBackground: (nodePathInfo: SequenceNodePathInfo | null, { hovered, selectedBackground, }: {
@@ -14,6 +14,7 @@ const pointer_session_1 = require("../../helpers/pointer-session");
14
14
  const timeline_layout_1 = require("../../helpers/timeline-layout");
15
15
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
16
16
  const use_keybinding_1 = require("../../helpers/use-keybinding");
17
+ const use_sync_external_store_1 = require("../../helpers/use-sync-external-store");
17
18
  const z_index_1 = require("../../state/z-index");
18
19
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
19
20
  const options_sidebar_tabs_1 = require("../options-sidebar-tabs");
@@ -225,6 +226,7 @@ const defaultTimelineSelectionContextValue = {
225
226
  clearSelection: () => undefined,
226
227
  };
227
228
  const TimelineSelectionContext = (0, react_1.createContext)(defaultTimelineSelectionContextValue);
229
+ const TimelineRowSelectionContext = (0, react_1.createContext)(null);
228
230
  const EMPTY_SELECTABLE_TIMELINE_ITEMS = [];
229
231
  const SelectableTimelineItemsContext = (0, react_1.createContext)({ current: EMPTY_SELECTABLE_TIMELINE_ITEMS });
230
232
  const TimelineSelectionOrderProvider = ({ children, items }) => {
@@ -561,6 +563,9 @@ const TimelineSelectionProvider = ({ children }) => {
561
563
  ? selectionState
562
564
  : exports.EMPTY_TIMELINE_SELECTION_STATE;
563
565
  const availableSelectedItems = availableSelectionState.selectedItems;
566
+ const getAvailableSelectionState = (0, react_1.useCallback)(() => selectionScope.current === timelineSelectionScope
567
+ ? selectionController.getSnapshot()
568
+ : exports.EMPTY_TIMELINE_SELECTION_STATE, [selectionController, timelineSelectionScope]);
564
569
  const requestRevealSelectionItem = (0, react_1.useCallback)((item) => {
565
570
  setRevealRequest((previousRequest) => {
566
571
  var _a;
@@ -790,9 +795,24 @@ const TimelineSelectionProvider = ({ children }) => {
790
795
  ]);
791
796
  const currentSelection = (0, react_1.useRef)(value);
792
797
  currentSelection.current = value;
793
- return (jsx_runtime_1.jsx(CurrentTimelineSelectionContext.Provider, { value: currentSelection, children: jsx_runtime_1.jsxs(TimelineSelectionContext.Provider, { value: value, children: [children, jsx_runtime_1.jsx(TimelineEscapeKeybindings, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
794
- jsx_runtime_1.jsx(TimelineClipboardKeybindings_1.TimelineClipboardKeybindings, {}), jsx_runtime_1.jsx(TimelineDeleteKeybindings_1.TimelineDeleteKeybindings, {})
795
- ] })) : null] }) }));
798
+ const rowSelectionContextValue = (0, react_1.useMemo)(() => ({
799
+ canSelect,
800
+ clearSelection,
801
+ getSnapshot: getAvailableSelectionState,
802
+ registerMarqueeSelectableItem,
803
+ selectItem,
804
+ subscribe: selectionController.subscribe,
805
+ }), [
806
+ canSelect,
807
+ clearSelection,
808
+ getAvailableSelectionState,
809
+ registerMarqueeSelectableItem,
810
+ selectItem,
811
+ selectionController.subscribe,
812
+ ]);
813
+ return (jsx_runtime_1.jsx(CurrentTimelineSelectionContext.Provider, { value: currentSelection, children: jsx_runtime_1.jsx(TimelineRowSelectionContext.Provider, { value: rowSelectionContextValue, children: jsx_runtime_1.jsxs(TimelineSelectionContext.Provider, { value: value, children: [children, jsx_runtime_1.jsx(TimelineEscapeKeybindings, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
814
+ jsx_runtime_1.jsx(TimelineClipboardKeybindings_1.TimelineClipboardKeybindings, {}), jsx_runtime_1.jsx(TimelineDeleteKeybindings_1.TimelineDeleteKeybindings, {})
815
+ ] })) : null] }) }) }));
796
816
  };
797
817
  exports.TimelineSelectionProvider = TimelineSelectionProvider;
798
818
  const useTimelineSelection = () => {
@@ -974,7 +994,11 @@ const useTimelineMarqueeSelection = () => {
974
994
  };
975
995
  exports.useTimelineMarqueeSelection = useTimelineMarqueeSelection;
976
996
  const useTimelineMarqueeSelectableItem = (item, ref) => {
977
- const { registerMarqueeSelectableItem } = (0, exports.useTimelineSelection)();
997
+ const selectionContext = (0, react_1.useContext)(TimelineRowSelectionContext);
998
+ if (selectionContext === null) {
999
+ throw new Error('useTimelineMarqueeSelectableItem must be used inside TimelineSelectionProvider');
1000
+ }
1001
+ const { registerMarqueeSelectableItem } = selectionContext;
978
1002
  (0, react_1.useEffect)(() => {
979
1003
  if (item === null) {
980
1004
  return;
@@ -988,47 +1012,68 @@ const useTimelineMarqueeSelectableItem = (item, ref) => {
988
1012
  };
989
1013
  exports.useTimelineMarqueeSelectableItem = useTimelineMarqueeSelectableItem;
990
1014
  const useTimelineRowSelection = (nodePathInfo, revealInInspector = false) => {
991
- const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
992
- const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
993
1015
  const selectionItem = (0, react_1.useMemo)(() => (0, exports.getTimelineSelectionFromNodePathInfo)(nodePathInfo), [nodePathInfo]);
994
- const selected = selectionItem === null ? false : isSelected(selectionItem);
1016
+ return useTimelineSelectionItem({
1017
+ revealInInspector,
1018
+ selectionItem,
1019
+ useSelectionOrder: true,
1020
+ });
1021
+ };
1022
+ exports.useTimelineRowSelection = useTimelineRowSelection;
1023
+ const useTimelineSelectionItem = ({ revealInInspector, selectionItem, useSelectionOrder, }) => {
1024
+ var _a;
1025
+ const selectionContext = (0, react_1.useContext)(TimelineRowSelectionContext);
1026
+ if (selectionContext === null) {
1027
+ throw new Error('useTimelineSelectionItem must be used inside TimelineSelectionProvider');
1028
+ }
1029
+ const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
1030
+ const selectionItemKey = (0, react_1.useMemo)(() => selectionItem === null ? null : (0, exports.getTimelineSelectionKey)(selectionItem), [selectionItem]);
1031
+ const getSelectedState = (0, react_1.useCallback)(() => {
1032
+ if (selectionItemKey === null) {
1033
+ return null;
1034
+ }
1035
+ const snapshot = selectionContext.getSnapshot();
1036
+ return snapshot.selectedItems.some((item) => (0, exports.getTimelineSelectionKey)(item) === selectionItemKey)
1037
+ ? snapshot
1038
+ : null;
1039
+ }, [selectionContext, selectionItemKey]);
1040
+ const selectedState = (0, use_sync_external_store_1.useSyncExternalStore)(selectionContext.subscribe, getSelectedState, getSelectedState);
995
1041
  const onSelect = (0, react_1.useCallback)((interaction) => {
996
1042
  if (selectionItem === null) {
997
1043
  return;
998
1044
  }
999
- selectItem(selectionItem, interaction, selectableTimelineItemsRef.current, { revealInInspector });
1000
- }, [revealInInspector, selectItem, selectableTimelineItemsRef, selectionItem]);
1045
+ selectionContext.selectItem(selectionItem, interaction, useSelectionOrder ? selectableTimelineItemsRef.current : undefined, { revealInInspector });
1046
+ }, [
1047
+ revealInInspector,
1048
+ selectableTimelineItemsRef,
1049
+ selectionContext,
1050
+ selectionItem,
1051
+ useSelectionOrder,
1052
+ ]);
1001
1053
  return {
1054
+ clearSelection: selectionContext.clearSelection,
1002
1055
  onSelect,
1003
- selectable: canSelect && selectionItem !== null,
1056
+ selectable: selectionContext.canSelect && selectionItem !== null,
1057
+ selectedItems: (_a = selectedState === null || selectedState === void 0 ? void 0 : selectedState.selectedItems) !== null && _a !== void 0 ? _a : exports.EMPTY_TIMELINE_SELECTION_STATE.selectedItems,
1058
+ selectItem: selectionContext.selectItem,
1004
1059
  selectionItem,
1005
- selected,
1060
+ selected: selectedState !== null,
1006
1061
  };
1007
1062
  };
1008
- exports.useTimelineRowSelection = useTimelineRowSelection;
1009
1063
  const useTimelineKeyframeSelection = (nodePathInfo, frame) => {
1010
- const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
1011
- const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
1012
1064
  const selectionItem = (0, react_1.useMemo)(() => ({
1013
1065
  type: 'keyframe',
1014
1066
  nodePathInfo,
1015
1067
  frame,
1016
1068
  }), [nodePathInfo, frame]);
1017
- const selected = isSelected(selectionItem);
1018
- const onSelect = (0, react_1.useCallback)((interaction) => {
1019
- selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
1020
- }, [selectItem, selectableTimelineItemsRef, selectionItem]);
1021
- return {
1022
- onSelect,
1023
- selectable: canSelect,
1069
+ return useTimelineSelectionItem({
1070
+ revealInInspector: false,
1024
1071
  selectionItem,
1025
- selected,
1026
- };
1072
+ useSelectionOrder: true,
1073
+ });
1027
1074
  };
1028
1075
  exports.useTimelineKeyframeSelection = useTimelineKeyframeSelection;
1029
1076
  const useTimelineEasingSelection = ({ nodePathInfo, fromFrame, toFrame, segmentIndex, }) => {
1030
- const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
1031
- const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
1032
1077
  const selectionItem = (0, react_1.useMemo)(() => ({
1033
1078
  type: 'easing',
1034
1079
  nodePathInfo,
@@ -1036,43 +1081,40 @@ const useTimelineEasingSelection = ({ nodePathInfo, fromFrame, toFrame, segmentI
1036
1081
  toFrame,
1037
1082
  segmentIndex,
1038
1083
  }), [nodePathInfo, fromFrame, segmentIndex, toFrame]);
1039
- const selected = isSelected(selectionItem);
1040
- const onSelect = (0, react_1.useCallback)((interaction) => {
1041
- selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
1042
- }, [selectItem, selectableTimelineItemsRef, selectionItem]);
1043
- return {
1044
- onSelect,
1045
- selectable: canSelect,
1046
- selected,
1084
+ return useTimelineSelectionItem({
1085
+ revealInInspector: false,
1047
1086
  selectionItem,
1048
- };
1087
+ useSelectionOrder: true,
1088
+ });
1049
1089
  };
1050
1090
  exports.useTimelineEasingSelection = useTimelineEasingSelection;
1051
1091
  const useTimelineGuideSelection = (guideId) => {
1052
- const { canSelect, clearSelection, isSelected, selectItem } = (0, exports.useTimelineSelection)();
1053
1092
  const selectionItem = (0, react_1.useMemo)(() => ({
1054
1093
  type: 'guide',
1055
1094
  guideId,
1056
1095
  }), [guideId]);
1057
- const selected = isSelected(selectionItem);
1058
- const onSelect = (0, react_1.useCallback)(() => {
1059
- selectItem(selectionItem);
1060
- }, [selectItem, selectionItem]);
1061
- return {
1062
- clearSelection,
1063
- onSelect,
1064
- selectable: canSelect,
1065
- selected,
1096
+ return useTimelineSelectionItem({
1097
+ revealInInspector: false,
1066
1098
  selectionItem,
1067
- };
1099
+ useSelectionOrder: false,
1100
+ });
1068
1101
  };
1069
1102
  exports.useTimelineGuideSelection = useTimelineGuideSelection;
1070
1103
  const useTimelineRowContainsSelection = (nodePathInfo) => {
1071
- const { containsSelection } = (0, exports.useTimelineSelection)();
1072
- if (nodePathInfo === null) {
1073
- return false;
1104
+ const selectionContext = (0, react_1.useContext)(TimelineRowSelectionContext);
1105
+ if (selectionContext === null) {
1106
+ throw new Error('useTimelineRowContainsSelection must be used inside TimelineSelectionProvider');
1074
1107
  }
1075
- return containsSelection(nodePathInfo);
1108
+ const getContainsSelection = (0, react_1.useCallback)(() => {
1109
+ if (nodePathInfo === null) {
1110
+ return false;
1111
+ }
1112
+ return selectionContext
1113
+ .getSnapshot()
1114
+ .selectedItems.some((selected) => selected.type !== 'guide' &&
1115
+ nodePathDescendsFrom(selected.nodePathInfo, nodePathInfo));
1116
+ }, [nodePathInfo, selectionContext]);
1117
+ return (0, use_sync_external_store_1.useSyncExternalStore)(selectionContext.subscribe, getContainsSelection, getContainsSelection);
1076
1118
  };
1077
1119
  exports.useTimelineRowContainsSelection = useTimelineRowContainsSelection;
1078
1120
  const useTimelineRowHighlightBackground = (nodePathInfo, { hovered, selectedBackground, }) => {