@remotion/studio 4.0.525 → 4.0.526

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 (141) 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 +21 -18
  10. package/dist/components/CaptionInspector.js +9 -3
  11. package/dist/{error-overlay/remotion-overlay → components}/CodeFrame.d.ts +2 -0
  12. package/dist/components/CodeFrame.js +77 -0
  13. package/dist/components/CompositionSelectorItem.js +6 -17
  14. package/dist/components/CurrentAsset.js +5 -4
  15. package/dist/components/ElementInstallConfirmation.js +69 -38
  16. package/dist/components/FilePreview.js +4 -0
  17. package/dist/components/FixComputedValueModal.js +64 -96
  18. package/dist/components/GenerateWithAgentModal.d.ts +9 -0
  19. package/dist/components/GenerateWithAgentModal.js +39 -0
  20. package/dist/components/InlineEditableTitle.js +2 -0
  21. package/dist/components/InspectorOpenInEditor.js +8 -4
  22. package/dist/components/InspectorPanel/CollapsibleInspectorSection.d.ts +7 -0
  23. package/dist/components/InspectorPanel/CollapsibleInspectorSection.js +14 -0
  24. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.d.ts +1 -1
  25. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +19 -8
  26. package/dist/components/InspectorPanel/CompositionInspector.js +30 -13
  27. package/dist/components/InspectorPanel/CompositionMetadata.js +3 -0
  28. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +6 -12
  29. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -0
  30. package/dist/components/InspectorPanel/GuideInspector.js +2 -3
  31. package/dist/components/InspectorPanel/KeyframeSettings.js +5 -6
  32. package/dist/components/InspectorPanel/MultiSequenceInspector.js +2 -1
  33. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -3
  34. package/dist/components/InspectorPanel/common.d.ts +4 -0
  35. package/dist/components/InspectorPanel/common.js +14 -2
  36. package/dist/components/InspectorPanel/styles.d.ts +0 -3
  37. package/dist/components/InspectorPanel/styles.js +1 -27
  38. package/dist/components/InspectorPanel/use-composition-actions.d.ts +2 -0
  39. package/dist/components/InspectorPanel/use-composition-actions.js +15 -0
  40. package/dist/components/InspectorPanel/use-inspector-section-expanded.d.ts +1 -0
  41. package/dist/components/InspectorPanel/use-inspector-section-expanded.js +21 -0
  42. package/dist/components/InspectorSequenceSection.js +44 -35
  43. package/dist/components/InspectorSourceLocation.js +1 -0
  44. package/dist/components/KeyboardShortcutsSettings.js +12 -4
  45. package/dist/components/LutPreview.d.ts +4 -0
  46. package/dist/components/LutPreview.js +192 -0
  47. package/dist/components/MenuCompositionName.js +4 -9
  48. package/dist/components/Modals.js +3 -6
  49. package/dist/components/ModelsSettings.js +15 -4
  50. package/dist/components/Notifications/NotificationCenter.d.ts +0 -1
  51. package/dist/components/Notifications/NotificationCenter.js +1 -22
  52. package/dist/components/QuickSwitcher/QuickSwitcherResult.js +4 -9
  53. package/dist/components/RenderModal/SchemaEditor/scroll-to-default-props-path.d.ts +1 -0
  54. package/dist/components/RenderModal/SchemaEditor/scroll-to-default-props-path.js +2 -1
  55. package/dist/components/RenderModal/WebRenderModal.js +10 -2
  56. package/dist/components/RendersTab.js +2 -0
  57. package/dist/components/SelectedOutlineElement.js +6 -0
  58. package/dist/components/SettingsButton.js +11 -2
  59. package/dist/components/SettingsModal.d.ts +1 -2
  60. package/dist/components/SettingsModal.js +24 -6
  61. package/dist/components/SettingsModalFooter.js +17 -3
  62. package/dist/components/SkillsSettings.d.ts +5 -0
  63. package/dist/components/SkillsSettings.js +29 -26
  64. package/dist/components/Timeline/Timeline.js +10 -11
  65. package/dist/components/Timeline/TimelineAssetField.js +81 -51
  66. package/dist/components/Timeline/TimelineHeightContainer.js +11 -1
  67. package/dist/components/Timeline/TimelineKeyframeControls.js +15 -1
  68. package/dist/components/Timeline/TimelineLayerChildren.d.ts +3 -3
  69. package/dist/components/Timeline/TimelineLayerChildren.js +11 -9
  70. package/dist/components/Timeline/TimelineLayerEye.d.ts +1 -1
  71. package/dist/components/Timeline/TimelineLayerEye.js +6 -3
  72. package/dist/components/Timeline/TimelineList.js +9 -3
  73. package/dist/components/Timeline/TimelineSchemaField.js +2 -6
  74. package/dist/components/Timeline/TimelineSelection.d.ts +14 -3
  75. package/dist/components/Timeline/TimelineSelection.js +91 -49
  76. package/dist/components/Timeline/TimelineSequence.js +2 -2
  77. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -0
  78. package/dist/components/Timeline/TimelineSequenceItem.js +17 -13
  79. package/dist/components/Timeline/TimelineVirtualization.d.ts +3 -3
  80. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +3 -1
  81. package/dist/components/Timeline/get-sequence-context-menu-items.js +130 -45
  82. package/dist/components/Timeline/normalize-font-weight-for-keyframe.d.ts +1 -0
  83. package/dist/components/Timeline/normalize-font-weight-for-keyframe.js +19 -0
  84. package/dist/components/Timeline/timeline-display-groups.d.ts +9 -0
  85. package/dist/components/Timeline/timeline-display-groups.js +66 -0
  86. package/dist/components/Timeline/use-timeline-asset-drop.js +21 -21
  87. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  88. package/dist/components/Timeline/use-timeline-expanded-tree.js +1 -2
  89. package/dist/components/UpdateStatusContext.d.ts +2 -2
  90. package/dist/components/UpdateStatusContext.js +6 -7
  91. package/dist/components/UpdatesSettings.js +6 -6
  92. package/dist/components/WebMcp.js +40 -41
  93. package/dist/components/asset-context-menu.d.ts +32 -0
  94. package/dist/components/asset-context-menu.js +242 -0
  95. package/dist/components/composition-menu-items.d.ts +4 -6
  96. package/dist/components/composition-menu-items.js +191 -75
  97. package/dist/components/get-open-in-menu-items.d.ts +6 -5
  98. package/dist/components/get-open-in-menu-items.js +15 -9
  99. package/dist/components/selected-outline-order.js +18 -12
  100. package/dist/components/use-open-in-menu-apps.d.ts +14 -0
  101. package/dist/components/use-open-in-menu-apps.js +33 -0
  102. package/dist/error-overlay/remotion-overlay/ErrorDisplay.js +2 -2
  103. package/dist/error-overlay/remotion-overlay/OpenInEditor.d.ts +1 -0
  104. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +3 -3
  105. package/dist/error-overlay/remotion-overlay/StackFrame.d.ts +5 -1
  106. package/dist/error-overlay/remotion-overlay/StackFrame.js +26 -19
  107. package/dist/esm/{LazyModels-gfmpcy4h.mjs → LazyModels-mtggyjye.mjs} +3 -3
  108. package/dist/esm/{LazyModels-m1rf06wh.mjs → LazyModels-nk7py0zt.mjs} +3 -3
  109. package/dist/esm/{TranscriptionModal-8pvrehg4.mjs → TranscriptionModal-ymnx1c7m.mjs} +6 -6
  110. package/dist/esm/{VideoMattingModal-fefbzgka.mjs → VideoMattingModal-05vpczks.mjs} +6 -6
  111. package/dist/esm/{index-s848rffx.mjs → index-0gewwxse.mjs} +5330 -4668
  112. package/dist/esm/{index-tzxb8808.mjs → index-4dsz9035.mjs} +8 -8
  113. package/dist/esm/{index-hbezgbbq.mjs → index-5bfxbpca.mjs} +1 -1
  114. package/dist/esm/{index-vsxrxfpj.mjs → index-5gd8k9yv.mjs} +1 -1
  115. package/dist/esm/{index-ggqpre9v.mjs → index-bs39wngg.mjs} +4216 -3571
  116. package/dist/esm/{index-0x13f28h.mjs → index-cdy8v54v.mjs} +1 -1
  117. package/dist/esm/{index-41kqns5c.mjs → index-eb5txqp6.mjs} +8 -7
  118. package/dist/esm/{index-1089795y.mjs → index-f97r9e2g.mjs} +4 -21
  119. package/dist/esm/{index-jrw61pkj.mjs → index-g7k2dvar.mjs} +1 -1
  120. package/dist/esm/{index-mww32xc8.mjs → index-x40wwfmt.mjs} +3 -3
  121. package/dist/esm/index.mjs +12 -6
  122. package/dist/esm/internals.mjs +7 -7
  123. package/dist/esm/previewEntry.mjs +7 -7
  124. package/dist/helpers/client-id.d.ts +1 -0
  125. package/dist/helpers/client-id.js +8 -4
  126. package/dist/helpers/cube-lut.d.ts +12 -0
  127. package/dist/helpers/cube-lut.js +160 -0
  128. package/dist/helpers/get-preview-file-type.d.ts +1 -1
  129. package/dist/helpers/get-preview-file-type.js +3 -0
  130. package/dist/helpers/open-in-editor.d.ts +5 -2
  131. package/dist/helpers/open-in-editor.js +12 -4
  132. package/dist/helpers/settings-tab-availability.d.ts +14 -0
  133. package/dist/helpers/settings-tab-availability.js +35 -0
  134. package/dist/helpers/use-menu-structure.js +16 -12
  135. package/dist/icons/lut.d.ts +4 -0
  136. package/dist/icons/lut.js +6 -0
  137. package/dist/icons/sparkles.d.ts +4 -0
  138. package/dist/icons/sparkles.js +6 -0
  139. package/dist/state/modals.d.ts +12 -2
  140. package/package.json +19 -19
  141. package/dist/error-overlay/remotion-overlay/CodeFrame.js +0 -62
@@ -10,6 +10,8 @@ const colors_1 = require("../../helpers/colors");
10
10
  const hoverable_1 = require("../../helpers/hoverable");
11
11
  const pen_1 = require("../../icons/pen");
12
12
  const modals_1 = require("../../state/modals");
13
+ const asset_context_menu_1 = require("../asset-context-menu");
14
+ const ContextMenu_1 = require("../ContextMenu");
13
15
  const import_assets_1 = require("../import-assets");
14
16
  const InlineAction_1 = require("../InlineAction");
15
17
  const common_1 = require("../InspectorPanel/common");
@@ -44,24 +46,35 @@ const imageAssetField = {
44
46
  alignItems: 'center',
45
47
  display: 'flex',
46
48
  flex: 1,
47
- gap: 8,
49
+ gap: 4,
50
+ margin: '0 4px',
51
+ minWidth: 0,
52
+ };
53
+ const imageAssetPreviewContainer = {
54
+ display: 'flex',
55
+ flex: 1,
48
56
  minWidth: 0,
49
- padding: '4px 12px',
50
57
  };
51
- const thumbnailButton = {
52
- ...(0, hoverable_1.hoverableStyle)({
53
- idleBackground: colors_1.TRANSPARENT,
54
- hoverBackground: colors_1.TRANSPARENT,
55
- idleColor: colors_1.LIGHT_TEXT,
56
- hoverColor: colors_1.WHITE,
57
- }),
58
+ const imageAssetPreviewButton = {
59
+ alignItems: 'center',
58
60
  appearance: 'none',
59
61
  border: 'none',
62
+ borderRadius: 4,
60
63
  cursor: 'default',
61
- flexShrink: 0,
64
+ display: 'flex',
65
+ flex: 1,
66
+ gap: 8,
62
67
  height: 40,
63
68
  margin: 0,
64
- padding: 0,
69
+ minWidth: 0,
70
+ padding: '0 8px',
71
+ textAlign: 'left',
72
+ };
73
+ const thumbnailContainer = {
74
+ borderRadius: 4,
75
+ flexShrink: 0,
76
+ height: 40,
77
+ overflow: 'hidden',
65
78
  width: 40,
66
79
  };
67
80
  const thumbnail = {
@@ -71,22 +84,11 @@ const thumbnail = {
71
84
  width: '100%',
72
85
  };
73
86
  const imageAssetInfo = {
74
- ...(0, hoverable_1.hoverableStyle)({
75
- idleBackground: colors_1.TRANSPARENT,
76
- hoverBackground: colors_1.TRANSPARENT,
77
- idleColor: colors_1.LIGHT_TEXT,
78
- hoverColor: colors_1.WHITE,
79
- }),
80
- appearance: 'none',
81
- border: 'none',
82
87
  display: 'flex',
83
88
  flex: 1,
84
89
  flexDirection: 'column',
85
90
  gap: 2,
86
- margin: 0,
87
91
  minWidth: 0,
88
- padding: 0,
89
- textAlign: 'left',
90
92
  };
91
93
  const imageAssetName = {
92
94
  color: colors_1.WHITE,
@@ -127,6 +129,14 @@ const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragV
127
129
  const { getSourceAction, sourceAction } = (0, react_1.useContext)(exports.AssetSelectionContext);
128
130
  const { assetType } = field.fieldSchema;
129
131
  const initialQuery = assetType ? `type:${assetType} ` : '';
132
+ const imageLinkInfo = assetType === 'image' && typeof effectiveValue === 'string'
133
+ ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(effectiveValue)
134
+ : null;
135
+ const localAssetPath = (imageLinkInfo === null || imageLinkInfo === void 0 ? void 0 : imageLinkInfo.kind) === 'local' ? imageLinkInfo.assetPath : null;
136
+ const { getContextMenuItems: getLocalAssetContextMenuItems } = (0, asset_context_menu_1.useAssetContextMenuItems)({
137
+ relativePath: localAssetPath,
138
+ readOnlyStudio: window.remotion_isReadOnlyStudio,
139
+ });
130
140
  const inlineSourceAction = (0, react_1.useMemo)(() => {
131
141
  if (typeof effectiveValue === 'string') {
132
142
  return getSourceAction(effectiveValue);
@@ -220,38 +230,58 @@ const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragV
220
230
  setSelectedModal,
221
231
  ]);
222
232
  const action = (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: openAssetSelection, disabled: window.remotion_isReadOnlyStudio, title: "Change source", renderAction: (color) => jsx_runtime_1.jsx(pen_1.PenIcon, { color: color, style: penIcon }) }));
223
- if (assetType === 'image' && typeof effectiveValue === 'string') {
224
- const linkInfo = (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(effectiveValue);
225
- if (linkInfo !== null) {
226
- let name;
227
- let source;
228
- let previewSrc;
229
- if (linkInfo.kind === 'local') {
230
- name = (_a = linkInfo.assetPath.split('/').pop()) !== null && _a !== void 0 ? _a : linkInfo.assetPath;
231
- source = 'Project asset';
232
- previewSrc = (0, remotion_1.staticFile)(linkInfo.assetPath);
233
+ if (imageLinkInfo !== null) {
234
+ const linkInfo = imageLinkInfo;
235
+ let name;
236
+ let source;
237
+ let previewSrc;
238
+ if (linkInfo.kind === 'local') {
239
+ name = (_a = linkInfo.assetPath.split('/').pop()) !== null && _a !== void 0 ? _a : linkInfo.assetPath;
240
+ source = null;
241
+ previewSrc = (0, remotion_1.staticFile)(linkInfo.assetPath);
242
+ }
243
+ else {
244
+ previewSrc = linkInfo.href.startsWith('//')
245
+ ? `https:${linkInfo.href}`
246
+ : linkInfo.href;
247
+ try {
248
+ const url = new URL(previewSrc);
249
+ const encodedName = url.pathname.split('/').filter(Boolean).pop();
250
+ name = encodedName ? decodeURIComponent(encodedName) : url.hostname;
251
+ source = url.hostname;
233
252
  }
234
- else {
235
- previewSrc = linkInfo.href.startsWith('//')
236
- ? `https:${linkInfo.href}`
237
- : linkInfo.href;
238
- try {
239
- const url = new URL(previewSrc);
240
- const encodedName = url.pathname.split('/').filter(Boolean).pop();
241
- name = encodedName ? decodeURIComponent(encodedName) : url.hostname;
242
- source = url.hostname;
243
- }
244
- catch (_c) {
245
- name = 'Remote image';
246
- source = linkInfo.href;
247
- }
253
+ catch (_c) {
254
+ name = 'Remote image';
255
+ source = linkInfo.href;
248
256
  }
249
- const title = (_b = inlineSourceAction === null || inlineSourceAction === void 0 ? void 0 : inlineSourceAction.title) !== null && _b !== void 0 ? _b : linkInfo.title;
250
- return (jsx_runtime_1.jsxs("div", { style: imageAssetField, children: [
251
- jsx_runtime_1.jsx("button", { "aria-label": `Replace ${name}`, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, disabled: window.remotion_isReadOnlyStudio, onClick: openAssetSelection, style: thumbnailButton, title: title, type: "button", children: jsx_runtime_1.jsx("img", { alt: "", src: previewSrc, style: thumbnail }) }), jsx_runtime_1.jsxs("button", { "aria-label": `Replace ${name}`, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, disabled: window.remotion_isReadOnlyStudio, onClick: openAssetSelection, style: imageAssetInfo, title: title, type: "button", children: [
252
- jsx_runtime_1.jsx("span", { style: imageAssetName, children: name }), jsx_runtime_1.jsx("span", { style: imageAssetSource, children: source })
253
- ] }), action] }));
254
257
  }
258
+ const opensSource = linkInfo.kind === 'local' &&
259
+ inlineSourceAction !== null &&
260
+ inlineSourceAction.onClick !== null;
261
+ const title = (_b = inlineSourceAction === null || inlineSourceAction === void 0 ? void 0 : inlineSourceAction.title) !== null && _b !== void 0 ? _b : linkInfo.title;
262
+ const onPreviewClick = opensSource
263
+ ? inlineSourceAction.onClick
264
+ : openAssetSelection;
265
+ const previewLabel = `${opensSource ? 'Open' : 'Replace'} ${name}`;
266
+ const previewDisabled = opensSource
267
+ ? inlineSourceAction.disabled
268
+ : window.remotion_isReadOnlyStudio;
269
+ const previewButtonStyle = {
270
+ ...imageAssetPreviewButton,
271
+ ...(0, hoverable_1.hoverableStyle)({
272
+ idleBackground: colors_1.TRANSPARENT,
273
+ hoverBackground: previewDisabled
274
+ ? colors_1.TRANSPARENT
275
+ : (0, colors_1.getBackgroundFromHoverState)({ hovered: true, selected: false }),
276
+ idleColor: colors_1.LIGHT_TEXT,
277
+ hoverColor: previewDisabled ? colors_1.LIGHT_TEXT : colors_1.WHITE,
278
+ }),
279
+ };
280
+ const previewAction = (jsx_runtime_1.jsxs("button", { "aria-label": previewLabel, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, disabled: previewDisabled, onClick: onPreviewClick, style: previewButtonStyle, title: title, type: "button", children: [
281
+ jsx_runtime_1.jsx("span", { style: thumbnailContainer, children: jsx_runtime_1.jsx("img", { alt: "", draggable: false, src: previewSrc, style: thumbnail }) }), jsx_runtime_1.jsxs("span", { style: imageAssetInfo, children: [
282
+ jsx_runtime_1.jsx("span", { style: imageAssetName, children: name }), source === null ? null : (jsx_runtime_1.jsx("span", { style: imageAssetSource, children: source }))] })
283
+ ] }));
284
+ return (jsx_runtime_1.jsxs("div", { style: imageAssetField, children: [localAssetPath === null ? (jsx_runtime_1.jsx("div", { style: imageAssetPreviewContainer, children: previewAction })) : (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getLocalAssetContextMenuItems, style: imageAssetPreviewContainer, children: previewAction })), action] }));
255
285
  }
256
286
  if (inlineSourceAction === null) {
257
287
  return action;
@@ -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");
@@ -222,12 +224,19 @@ const getAddChange = (target) => {
222
224
  if (value === null) {
223
225
  return null;
224
226
  }
227
+ const fieldSchema = target.schema[target.fieldKey];
228
+ const normalizedValue = (fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.type) === 'font-weight'
229
+ ? (0, normalize_font_weight_for_keyframe_1.normalizeFontWeightForKeyframe)(value)
230
+ : value;
231
+ if (normalizedValue === null) {
232
+ return null;
233
+ }
225
234
  const change = {
226
235
  fileName: target.fileName,
227
236
  nodePath: target.nodePath,
228
237
  fieldKey: target.fieldKey,
229
238
  sourceFrame: target.sourceFrame,
230
- value,
239
+ value: normalizedValue,
231
240
  schema: target.schema,
232
241
  };
233
242
  if (target.effectIndex === null) {
@@ -313,6 +322,7 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
313
322
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
314
323
  const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
315
324
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
325
+ const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
316
326
  const { selectedItems, selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
317
327
  const tracks = (0, TimelineKeyframeTracksContext_1.useTimelineKeyframeTracks)();
318
328
  const clientId = previewServerState.type === 'connected'
@@ -481,6 +491,9 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
481
491
  setPropStatuses,
482
492
  clientId,
483
493
  });
494
+ for (const { target } of addChanges) {
495
+ expandParentTracks(target.nodePathInfo);
496
+ }
484
497
  if (mode === 'timeline') {
485
498
  selectItems(addChanges.map(({ target }) => ({
486
499
  type: 'keyframe',
@@ -491,6 +504,7 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
491
504
  }, [
492
505
  canToggleKeyframe,
493
506
  clientId,
507
+ expandParentTracks,
494
508
  hasKeyframeAtCurrentFrame,
495
509
  keyframeToggleTargets,
496
510
  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, }: {