@remotion/studio 4.0.489 → 4.0.490

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 (47) hide show
  1. package/dist/components/Canvas.js +19 -2
  2. package/dist/components/InspectorPanel/AlignmentControls.d.ts +5 -0
  3. package/dist/components/InspectorPanel/AlignmentControls.js +205 -0
  4. package/dist/components/InspectorPanel/EasingInspector.js +8 -2
  5. package/dist/components/InspectorPanel/KeyframeSettings.d.ts +5 -0
  6. package/dist/components/InspectorPanel/KeyframeSettings.js +142 -0
  7. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +2 -1
  8. package/dist/components/InspectorPanel/alignment-controls.d.ts +12 -0
  9. package/dist/components/InspectorPanel/alignment-controls.js +42 -0
  10. package/dist/components/InspectorSequenceSection.d.ts +1 -0
  11. package/dist/components/InspectorSequenceSection.js +2 -2
  12. package/dist/components/MobilePanel.js +9 -3
  13. package/dist/components/Modals.js +1 -2
  14. package/dist/components/NewComposition/CancelButton.d.ts +1 -0
  15. package/dist/components/NewComposition/CancelButton.js +6 -2
  16. package/dist/components/Preview.js +1 -1
  17. package/dist/components/SelectedOutlineOverlay.d.ts +6 -1
  18. package/dist/components/SelectedOutlineOverlay.js +247 -9
  19. package/dist/components/Timeline/TimelineClipboardKeybindings.js +3 -0
  20. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -50
  21. package/dist/components/Timeline/TimelineSequenceItem.js +6 -9
  22. package/dist/components/Timeline/TimelineSequenceName.js +1 -3
  23. package/dist/components/Timeline/TimelineSequencePropItem.js +2 -49
  24. package/dist/components/import-assets.d.ts +1 -0
  25. package/dist/components/import-assets.js +1 -0
  26. package/dist/esm/{chunk-jrta3xaf.js → chunk-16nwrbrm.js} +4914 -4322
  27. package/dist/esm/internals.mjs +4914 -4322
  28. package/dist/esm/previewEntry.mjs +4952 -4360
  29. package/dist/esm/renderEntry.mjs +1 -1
  30. package/dist/helpers/install-required-package.d.ts +1 -0
  31. package/dist/helpers/install-required-package.js +3 -2
  32. package/dist/icons/align-bottom.d.ts +3 -0
  33. package/dist/icons/align-bottom.js +12 -0
  34. package/dist/icons/align-center-horizontal.d.ts +3 -0
  35. package/dist/icons/align-center-horizontal.js +12 -0
  36. package/dist/icons/align-center-vertical.d.ts +3 -0
  37. package/dist/icons/align-center-vertical.js +12 -0
  38. package/dist/icons/align-left.d.ts +3 -0
  39. package/dist/icons/align-left.js +12 -0
  40. package/dist/icons/align-right.d.ts +3 -0
  41. package/dist/icons/align-right.js +12 -0
  42. package/dist/icons/align-top.d.ts +3 -0
  43. package/dist/icons/align-top.js +12 -0
  44. package/dist/state/modals.d.ts +1 -2
  45. package/package.json +11 -11
  46. package/dist/components/Timeline/KeyframeSettingsModal.d.ts +0 -15
  47. package/dist/components/Timeline/KeyframeSettingsModal.js +0 -151
@@ -121,7 +121,7 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
121
121
  if (canvasContent.type === 'output-blob') {
122
122
  return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(RenderPreview_1.RenderPreview, { path: canvasContent.displayName, assetMetadata: assetMetadata, getBlob: canvasContent.getBlob }) }));
123
123
  }
124
- return (jsx_runtime_1.jsxs("div", { style: outer, children: [
124
+ return (jsx_runtime_1.jsxs("div", { className: "remotion-studio-composition-container", style: outer, children: [
125
125
  jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { compositionHeight: contentDimensions.height, compositionWidth: contentDimensions.width, scale: scale, translationX: previewSize.translation.x, translationY: previewSize.translation.y })
126
126
  ] }));
127
127
  };
@@ -5,8 +5,13 @@ export { applySelectedOutlineDragAxisLock, applySelectedOutlineTransformOriginAx
5
5
  export { getOutlineSelectionInteraction, getSelectedEffectFieldsBySequenceKey, getSelectedOutlineRotationCornerInfo, getSelectedOutlineRotationDeltaDegrees, getSelectedOutlineRotationPivot, getSelectedSequenceKeys, getSequencesWithSelectableOutlines, getTransformedSvgViewportPoints, } from './selected-outline-measurement';
6
6
  export { selectedOutlineDragThresholdPx } from './selected-outline-types';
7
7
  export type { SelectedOutlineDragState, SelectedOutlineRotationDragState, SelectedOutlineScaleDragState, } from './selected-outline-types';
8
- export declare const orderOutlinesForRendering: ({ outlines, targetsByKey, }: {
8
+ type OutlineSequenceParent = {
9
+ readonly id: string;
10
+ readonly parent: string | null;
11
+ };
12
+ export declare const orderOutlinesForRendering: ({ outlines, sequences, targetsByKey, }: {
9
13
  readonly outlines: readonly SelectedOutline[];
14
+ readonly sequences: readonly OutlineSequenceParent[];
10
15
  readonly targetsByKey: ReadonlyMap<string, SelectedOutlineTarget>;
11
16
  }) => readonly SelectedOutline[];
12
17
  export declare const SelectedOutlineOverlay: React.FC<{
@@ -111,13 +111,251 @@ const SelectedOutlineSnapIndicators = ({ activeSnapPoints, compositionHeight, co
111
111
  return (jsx_runtime_1.jsx("line", { x1: 0, x2: compositionWidth * scale, y1: y, y2: y, stroke: selected_outline_snap_1.selectedOutlineSnapIndicatorColor, strokeWidth: 1, vectorEffect: "non-scaling-stroke" }, `${snapPoint.target.axis}-${snapPoint.target.type}-${snapPoint.target.position}-${snapPoint.edge}`));
112
112
  }) }));
113
113
  };
114
- const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
115
- return [...outlines].sort((a, b) => {
116
- var _a, _b;
117
- var _c, _d;
118
- const aSelected = (_c = (_a = targetsByKey.get(a.key)) === null || _a === void 0 ? void 0 : _a.selected) !== null && _c !== void 0 ? _c : false;
119
- const bSelected = (_d = (_b = targetsByKey.get(b.key)) === null || _b === void 0 ? void 0 : _b.selected) !== null && _d !== void 0 ? _d : false;
120
- return Number(aSelected) - Number(bSelected);
114
+ const outlinePointEqualityTolerance = 0.5;
115
+ const outlineAreaEqualityTolerance = 0.5;
116
+ const outlineBoundsOverlapTolerance = 0.5;
117
+ const outlinePointsAreEquivalent = (a, b) => {
118
+ return (Math.abs(a.x - b.x) <= outlinePointEqualityTolerance &&
119
+ Math.abs(a.y - b.y) <= outlinePointEqualityTolerance);
120
+ };
121
+ const outlinesHaveEquivalentHitArea = (a, b) => {
122
+ if (a.points.length !== b.points.length) {
123
+ return false;
124
+ }
125
+ for (let startIndex = 0; startIndex < b.points.length; startIndex++) {
126
+ for (const direction of [1, -1]) {
127
+ const pointsMatch = a.points.every((point, index) => {
128
+ const bIndex = (startIndex + direction * index + b.points.length) % b.points.length;
129
+ return outlinePointsAreEquivalent(point, b.points[bIndex]);
130
+ });
131
+ if (pointsMatch) {
132
+ return true;
133
+ }
134
+ }
135
+ }
136
+ return false;
137
+ };
138
+ const getOutlineHitArea = (outline) => {
139
+ let area = 0;
140
+ for (let i = 0; i < outline.points.length; i++) {
141
+ const current = outline.points[i];
142
+ const next = outline.points[(i + 1) % outline.points.length];
143
+ area += current.x * next.y - next.x * current.y;
144
+ }
145
+ return Math.abs(area) / 2;
146
+ };
147
+ const getOutlineBounds = (outline) => {
148
+ const xs = outline.points.map((point) => point.x);
149
+ const ys = outline.points.map((point) => point.y);
150
+ return {
151
+ maxX: Math.max(...xs),
152
+ maxY: Math.max(...ys),
153
+ minX: Math.min(...xs),
154
+ minY: Math.min(...ys),
155
+ };
156
+ };
157
+ const outlineBoundsOverlap = (a, b) => {
158
+ const aBounds = getOutlineBounds(a);
159
+ const bBounds = getOutlineBounds(b);
160
+ return (aBounds.minX <= bBounds.maxX + outlineBoundsOverlapTolerance &&
161
+ aBounds.maxX + outlineBoundsOverlapTolerance >= bBounds.minX &&
162
+ aBounds.minY <= bBounds.maxY + outlineBoundsOverlapTolerance &&
163
+ aBounds.maxY + outlineBoundsOverlapTolerance >= bBounds.minY);
164
+ };
165
+ const getSequenceId = (target) => {
166
+ var _a;
167
+ var _b;
168
+ return (_b = (_a = target === null || target === void 0 ? void 0 : target.sequence) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
169
+ };
170
+ const getParentBySequenceId = ({ sequences, targetsByKey, }) => {
171
+ const parentBySequenceId = new Map();
172
+ for (const sequence of sequences) {
173
+ parentBySequenceId.set(sequence.id, sequence.parent);
174
+ }
175
+ for (const target of targetsByKey.values()) {
176
+ const sequenceId = getSequenceId(target);
177
+ if (sequenceId !== null && !parentBySequenceId.has(sequenceId)) {
178
+ parentBySequenceId.set(sequenceId, target.sequence.parent);
179
+ }
180
+ }
181
+ return parentBySequenceId;
182
+ };
183
+ const isAncestorTarget = ({ ancestor, descendant, parentBySequenceId, }) => {
184
+ var _a;
185
+ var _b, _c;
186
+ const ancestorId = getSequenceId(ancestor);
187
+ if (ancestorId === null) {
188
+ return false;
189
+ }
190
+ let parentId = (_b = (_a = descendant.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
191
+ while (parentId !== null) {
192
+ if (parentId === ancestorId) {
193
+ return true;
194
+ }
195
+ parentId = (_c = parentBySequenceId.get(parentId)) !== null && _c !== void 0 ? _c : null;
196
+ }
197
+ return false;
198
+ };
199
+ const orderOutlineGroup = ({ outlines, parentBySequenceId, targetsByKey, }) => {
200
+ var _a;
201
+ var _b, _c, _d, _e;
202
+ const incomingEdges = new Map();
203
+ const outgoingEdges = new Map();
204
+ const outlinesByKey = new Map(outlines.map((outline) => [outline.key, outline]));
205
+ for (const outline of outlines) {
206
+ incomingEdges.set(outline.key, new Set());
207
+ outgoingEdges.set(outline.key, new Set());
208
+ }
209
+ const hasPath = ({ fromKey, seen, toKey, }) => {
210
+ var _a;
211
+ if (fromKey === toKey) {
212
+ return true;
213
+ }
214
+ if (seen.has(fromKey)) {
215
+ return false;
216
+ }
217
+ seen.add(fromKey);
218
+ for (const nextKey of (_a = outgoingEdges.get(fromKey)) !== null && _a !== void 0 ? _a : []) {
219
+ if (hasPath({ fromKey: nextKey, seen, toKey })) {
220
+ return true;
221
+ }
222
+ }
223
+ return false;
224
+ };
225
+ const addEdge = (before, after, options) => {
226
+ if (before.key === after.key) {
227
+ return;
228
+ }
229
+ const incoming = incomingEdges.get(after.key);
230
+ const outgoing = outgoingEdges.get(before.key);
231
+ if (incoming === undefined || outgoing === undefined) {
232
+ throw new Error('Expected outline to be registered before adding edge');
233
+ }
234
+ if (outgoing.has(after.key)) {
235
+ return;
236
+ }
237
+ if (hasPath({ fromKey: after.key, seen: new Set(), toKey: before.key })) {
238
+ if (options === null || options === void 0 ? void 0 : options.skipIfCycle) {
239
+ return;
240
+ }
241
+ throw new Error('Could not determine a stable outline rendering order');
242
+ }
243
+ incoming.add(before.key);
244
+ outgoing.add(after.key);
245
+ };
246
+ const addAncestorConstraint = ({ ancestor, descendant, descendantContainsSelection, equivalentHitArea, }) => {
247
+ // Usually, children should be above parents so nested elements are directly
248
+ // selectable. If an unselected child has the same hit area as its parent, put
249
+ // it below the parent so the wrapper can be selected. Once the child or
250
+ // one of its properties is selected, keep it above the parent so it remains
251
+ // directly draggable.
252
+ if (equivalentHitArea && !descendantContainsSelection) {
253
+ addEdge(descendant, ancestor);
254
+ }
255
+ else {
256
+ addEdge(ancestor, descendant);
257
+ }
258
+ };
259
+ const outlineBySequenceId = new Map();
260
+ for (const outline of outlines) {
261
+ const sequenceId = getSequenceId(targetsByKey.get(outline.key));
262
+ if (sequenceId !== null) {
263
+ outlineBySequenceId.set(sequenceId, outline);
264
+ }
265
+ }
266
+ // Only constrain each outline against its nearest rendered ancestor. The
267
+ // resulting graph follows the sequence tree, so pairwise subpixel equivalence
268
+ // cannot introduce contradictory edges across three nested outlines.
269
+ for (const descendant of outlines) {
270
+ const descendantTarget = targetsByKey.get(descendant.key);
271
+ let parentId = (_b = (_a = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.sequence) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
272
+ while (parentId !== null) {
273
+ const ancestor = outlineBySequenceId.get(parentId);
274
+ if (ancestor !== undefined) {
275
+ addAncestorConstraint({
276
+ ancestor,
277
+ descendant,
278
+ descendantContainsSelection: ((_c = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.selected) !== null && _c !== void 0 ? _c : false) ||
279
+ ((_d = descendantTarget === null || descendantTarget === void 0 ? void 0 : descendantTarget.containsSelection) !== null && _d !== void 0 ? _d : false),
280
+ equivalentHitArea: outlinesHaveEquivalentHitArea(ancestor, descendant),
281
+ });
282
+ break;
283
+ }
284
+ parentId = (_e = parentBySequenceId.get(parentId)) !== null && _e !== void 0 ? _e : null;
285
+ }
286
+ }
287
+ // For unrelated overlapping outlines, put broader hit targets below
288
+ // smaller ones so a large selected sequence cannot swallow clicks on
289
+ // a more specific element in the same canvas area.
290
+ for (let i = 0; i < outlines.length; i++) {
291
+ for (let j = i + 1; j < outlines.length; j++) {
292
+ const a = outlines[i];
293
+ const b = outlines[j];
294
+ const aTarget = targetsByKey.get(a.key);
295
+ const bTarget = targetsByKey.get(b.key);
296
+ if (aTarget === undefined || bTarget === undefined) {
297
+ continue;
298
+ }
299
+ const aAncestorOfB = isAncestorTarget({
300
+ ancestor: aTarget,
301
+ descendant: bTarget,
302
+ parentBySequenceId,
303
+ });
304
+ const bAncestorOfA = isAncestorTarget({
305
+ ancestor: bTarget,
306
+ descendant: aTarget,
307
+ parentBySequenceId,
308
+ });
309
+ if (aAncestorOfB || bAncestorOfA || !outlineBoundsOverlap(a, b)) {
310
+ continue;
311
+ }
312
+ const aArea = getOutlineHitArea(a);
313
+ const bArea = getOutlineHitArea(b);
314
+ if (Math.abs(aArea - bArea) <= outlineAreaEqualityTolerance) {
315
+ continue;
316
+ }
317
+ if (aArea > bArea) {
318
+ addEdge(a, b, { skipIfCycle: true });
319
+ }
320
+ else {
321
+ addEdge(b, a, { skipIfCycle: true });
322
+ }
323
+ }
324
+ }
325
+ const emitted = new Set();
326
+ const visiting = new Set();
327
+ const ordered = [];
328
+ const visit = (outline) => {
329
+ var _a;
330
+ if (emitted.has(outline.key)) {
331
+ return;
332
+ }
333
+ if (visiting.has(outline.key)) {
334
+ throw new Error('Could not determine a stable outline rendering order');
335
+ }
336
+ visiting.add(outline.key);
337
+ for (const dependencyKey of (_a = incomingEdges.get(outline.key)) !== null && _a !== void 0 ? _a : []) {
338
+ const dependency = outlinesByKey.get(dependencyKey);
339
+ if (dependency === undefined) {
340
+ throw new Error('Expected outline dependency to exist');
341
+ }
342
+ visit(dependency);
343
+ }
344
+ visiting.delete(outline.key);
345
+ emitted.add(outline.key);
346
+ ordered.push(outline);
347
+ };
348
+ for (const outline of outlines) {
349
+ visit(outline);
350
+ }
351
+ return ordered;
352
+ };
353
+ const orderOutlinesForRendering = ({ outlines, sequences, targetsByKey, }) => {
354
+ const parentBySequenceId = getParentBySequenceId({ sequences, targetsByKey });
355
+ return orderOutlineGroup({
356
+ outlines,
357
+ parentBySequenceId,
358
+ targetsByKey,
121
359
  });
122
360
  };
123
361
  exports.orderOutlinesForRendering = orderOutlinesForRendering;
@@ -414,8 +652,8 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
414
652
  return new Map(outlineTargets.map((target) => [target.key, target]));
415
653
  }, [outlineTargets]);
416
654
  const outlinesForRendering = (0, react_1.useMemo)(() => {
417
- return (0, exports.orderOutlinesForRendering)({ outlines, targetsByKey });
418
- }, [outlines, targetsByKey]);
655
+ return (0, exports.orderOutlinesForRendering)({ outlines, sequences, targetsByKey });
656
+ }, [outlines, sequences, targetsByKey]);
419
657
  const outlinesByKey = (0, react_1.useMemo)(() => {
420
658
  return new Map(outlines.map((outline) => [outline.key, outline]));
421
659
  }, [outlines]);
@@ -90,6 +90,9 @@ const effectPropStatusToClipboardParam = (prop) => {
90
90
  keyframes: prop.keyframes,
91
91
  easing: prop.easing,
92
92
  clamping: prop.clamping,
93
+ ...(prop.output === undefined || prop.output === 'linear'
94
+ ? {}
95
+ : { output: prop.output }),
93
96
  ...(prop.posterize === undefined ? {} : { posterize: prop.posterize }),
94
97
  };
95
98
  };
@@ -6,7 +6,6 @@ const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const client_id_1 = require("../../helpers/client-id");
9
- const modals_1 = require("../../state/modals");
10
9
  const call_api_1 = require("../call-api");
11
10
  const ContextMenu_1 = require("../ContextMenu");
12
11
  const call_add_keyframe_1 = require("./call-add-keyframe");
@@ -216,7 +215,6 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
216
215
  var _a;
217
216
  var _b, _c;
218
217
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
219
- const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
220
218
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
221
219
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
222
220
  const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
@@ -302,33 +300,8 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
302
300
  setPropStatuses,
303
301
  validatedLocation.source,
304
302
  ]);
305
- const onOpenKeyframeSettings = (0, react_1.useCallback)(() => {
306
- var _a;
307
- if (propStatus === null || !isKeyframedStatus(propStatus)) {
308
- return;
309
- }
310
- setSelectedModal({
311
- type: 'keyframe-settings',
312
- fileName: validatedLocation.source,
313
- nodePath,
314
- fieldKey: field.key,
315
- fieldLabel: (_a = field.description) !== null && _a !== void 0 ? _a : field.key,
316
- status: propStatus,
317
- schema: field.effectSchema,
318
- effectIndex: field.effectIndex,
319
- });
320
- }, [
321
- field.description,
322
- field.effectIndex,
323
- field.effectSchema,
324
- field.key,
325
- nodePath,
326
- propStatus,
327
- setSelectedModal,
328
- validatedLocation.source,
329
- ]);
330
303
  const contextMenuValues = (0, react_1.useMemo)(() => {
331
- const values = [
304
+ return [
332
305
  {
333
306
  type: 'item',
334
307
  id: 'reset-effect-field',
@@ -342,28 +315,7 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
342
315
  value: 'reset-effect-field',
343
316
  },
344
317
  ];
345
- if (propStatus !== null && isKeyframedStatus(propStatus)) {
346
- values.push({
347
- type: 'item',
348
- id: 'keyframe-settings-effect-field',
349
- keyHint: null,
350
- label: 'Keyframe settings...',
351
- leftItem: null,
352
- disabled: previewServerState.type !== 'connected',
353
- onClick: onOpenKeyframeSettings,
354
- quickSwitcherLabel: null,
355
- subMenu: null,
356
- value: 'keyframe-settings-effect-field',
357
- });
358
- }
359
- return values;
360
- }, [
361
- canShowReset,
362
- onOpenKeyframeSettings,
363
- onReset,
364
- previewServerState,
365
- propStatus,
366
- ]);
318
+ }, [canShowReset, onReset]);
367
319
  const seekToDisplayFrame = (0, react_1.useCallback)((frame) => {
368
320
  setFrame((current) => {
369
321
  const next = { ...current, [videoConfig.id]: frame };
@@ -535,18 +535,17 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
535
535
  codeHiddenStatus !== undefined &&
536
536
  codeHiddenStatus !== null &&
537
537
  codeHiddenStatus.status === 'static';
538
- const onSequenceDoubleClick = (0, react_1.useCallback)((e) => {
538
+ const onShowInEditorDoubleClick = (0, react_1.useCallback)((e) => {
539
+ if (!canOpenInEditor) {
540
+ return;
541
+ }
539
542
  if ((0, TimelineSelection_1.isTimelineSelectionModifierEvent)(e)) {
540
543
  e.stopPropagation();
541
544
  return;
542
545
  }
543
546
  e.stopPropagation();
544
- if (canRenameThisSequence) {
545
- setIsRenaming(true);
546
- return;
547
- }
548
547
  openInEditor();
549
- }, [canRenameThisSequence, openInEditor]);
548
+ }, [canOpenInEditor, openInEditor]);
550
549
  const canRenameSelectedSequence = canRenameThisSequence &&
551
550
  selected &&
552
551
  selectedItems.length === 1 &&
@@ -766,9 +765,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
766
765
  clientId: previewServerState.clientId,
767
766
  });
768
767
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
769
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canRenameThisSequence || canOpenInEditor
770
- ? onSequenceDoubleClick
771
- : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [
768
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canOpenInEditor ? onShowInEditorDoubleClick : undefined, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [
772
769
  jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: displayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
773
770
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
774
771
  " ",
@@ -66,9 +66,7 @@ const TimelineSequenceName = ({ displayName, fallbackDisplayName, selected, cont
66
66
  return;
67
67
  }
68
68
  input.focus();
69
- const basenameIndex = editableDisplayName.lastIndexOf('.');
70
- const selectionEnd = basenameIndex > 0 ? basenameIndex : editableDisplayName.length;
71
- input.setSelectionRange(0, selectionEnd);
69
+ input.select();
72
70
  }, [editableDisplayName, editing]);
73
71
  const save = (0, react_1.useCallback)(() => {
74
72
  onSaveName(draftName).catch(() => undefined);
@@ -6,7 +6,6 @@ const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const client_id_1 = require("../../helpers/client-id");
9
- const modals_1 = require("../../state/modals");
10
9
  const ContextMenu_1 = require("../ContextMenu");
11
10
  const call_add_keyframe_1 = require("./call-add-keyframe");
12
11
  const get_animation_item_selection_for_frame_1 = require("./get-animation-item-selection-for-frame");
@@ -166,7 +165,6 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
166
165
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
167
166
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
168
167
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
169
- const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
170
168
  const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
171
169
  const { selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
172
170
  const setFrame = remotion_1.Internals.useTimelineSetFrame();
@@ -251,32 +249,8 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
251
249
  validatedLocation.source,
252
250
  propStatus,
253
251
  ]);
254
- const onOpenKeyframeSettings = (0, react_1.useCallback)(() => {
255
- var _a;
256
- if (propStatus === null || !isKeyframedStatus(propStatus)) {
257
- return;
258
- }
259
- setSelectedModal({
260
- type: 'keyframe-settings',
261
- fileName: validatedLocation.source,
262
- nodePath,
263
- fieldKey: field.key,
264
- fieldLabel: (_a = field.description) !== null && _a !== void 0 ? _a : field.key,
265
- status: propStatus,
266
- schema,
267
- effectIndex: null,
268
- });
269
- }, [
270
- propStatus,
271
- field.description,
272
- field.key,
273
- nodePath,
274
- schema,
275
- setSelectedModal,
276
- validatedLocation.source,
277
- ]);
278
252
  const contextMenuValues = (0, react_1.useMemo)(() => {
279
- const values = [
253
+ return [
280
254
  {
281
255
  type: 'item',
282
256
  id: 'reset-sequence-field',
@@ -290,28 +264,7 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
290
264
  value: 'reset-sequence-field',
291
265
  },
292
266
  ];
293
- if (propStatus !== null && isKeyframedStatus(propStatus)) {
294
- values.push({
295
- type: 'item',
296
- id: 'keyframe-settings-sequence-field',
297
- keyHint: null,
298
- label: 'Keyframe settings...',
299
- leftItem: null,
300
- disabled: previewServerState.type !== 'connected',
301
- onClick: onOpenKeyframeSettings,
302
- quickSwitcherLabel: null,
303
- subMenu: null,
304
- value: 'keyframe-settings-sequence-field',
305
- });
306
- }
307
- return values;
308
- }, [
309
- canShowReset,
310
- propStatus,
311
- onOpenKeyframeSettings,
312
- onReset,
313
- previewServerState,
314
- ]);
267
+ }, [canShowReset, onReset]);
315
268
  const seekToDisplayFrame = (0, react_1.useCallback)((frame) => {
316
269
  setFrame((current) => {
317
270
  const next = { ...current, [videoConfig.id]: frame };
@@ -83,6 +83,7 @@ export declare const insertElement: ({ compositionFile, compositionId, dropPosit
83
83
  compositionId: string;
84
84
  dropPosition: InsertElementDropPosition | null;
85
85
  element: {
86
+ dependencies: string[];
86
87
  slug: string;
87
88
  displayName: string;
88
89
  sourceCode: string;
@@ -625,6 +625,7 @@ const insertComposition = async ({ composition, compositionFile, compositionId,
625
625
  exports.insertComposition = insertComposition;
626
626
  const insertElement = async ({ compositionFile, compositionId, dropPosition, element, }) => {
627
627
  try {
628
+ await (0, install_required_package_1.installRequiredPackages)(element.dependencies);
628
629
  const response = await (0, call_api_1.callApi)('/api/insert-element', {
629
630
  compositionFile,
630
631
  compositionId,