@remotion/studio 4.0.458 → 4.0.460

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 (66) hide show
  1. package/dist/audio-waveform-worker.js +4 -4
  2. package/dist/components/AudioWaveform.js +4 -4
  3. package/dist/components/Checkbox.d.ts +7 -0
  4. package/dist/components/Checkbox.js +38 -24
  5. package/dist/components/Editor.js +10 -9
  6. package/dist/components/ExpandedTracksProvider.d.ts +9 -4
  7. package/dist/components/ExpandedTracksProvider.js +45 -15
  8. package/dist/components/MenuBuildIndicator.js +0 -1
  9. package/dist/components/NewComposition/ComboBox.d.ts +1 -0
  10. package/dist/components/NewComposition/ComboBox.js +14 -5
  11. package/dist/components/SequencePropsSubscriptionProvider.d.ts +3 -0
  12. package/dist/components/SequencePropsSubscriptionProvider.js +26 -0
  13. package/dist/components/Timeline/SequencePropsObserver.d.ts +1 -0
  14. package/dist/components/Timeline/SequencePropsObserver.js +24 -0
  15. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +7 -0
  16. package/dist/components/Timeline/SubscribeToNodePaths.js +15 -0
  17. package/dist/components/Timeline/Timeline.js +28 -48
  18. package/dist/components/Timeline/TimelineBooleanField.js +1 -1
  19. package/dist/components/Timeline/TimelineEnumField.js +18 -10
  20. package/dist/components/Timeline/TimelineExpandArrowButton.d.ts +1 -0
  21. package/dist/components/Timeline/TimelineExpandArrowButton.js +5 -3
  22. package/dist/components/Timeline/TimelineExpandedRow.d.ts +6 -6
  23. package/dist/components/Timeline/TimelineExpandedRow.js +4 -5
  24. package/dist/components/Timeline/TimelineExpandedSection.d.ts +2 -2
  25. package/dist/components/Timeline/TimelineExpandedSection.js +20 -9
  26. package/dist/components/Timeline/TimelineFieldRow.d.ts +2 -3
  27. package/dist/components/Timeline/TimelineFieldRow.js +23 -20
  28. package/dist/components/Timeline/TimelineHeightContainer.d.ts +7 -0
  29. package/dist/components/Timeline/TimelineHeightContainer.js +18 -0
  30. package/dist/components/Timeline/TimelineList.js +1 -1
  31. package/dist/components/Timeline/TimelineListItem.d.ts +2 -0
  32. package/dist/components/Timeline/TimelineListItem.js +27 -13
  33. package/dist/components/Timeline/TimelineSchemaField.js +4 -1
  34. package/dist/components/Timeline/TimelineTracks.js +18 -7
  35. package/dist/components/Timeline/TimelineVideoInfo.js +25 -140
  36. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +10 -13
  37. package/dist/components/Timeline/sequence-props-subscription-store.js +56 -123
  38. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +6 -6
  39. package/dist/components/Timeline/use-sequence-props-subscription.js +25 -55
  40. package/dist/components/Timeline/use-timeline-height.d.ts +5 -0
  41. package/dist/components/Timeline/use-timeline-height.js +48 -0
  42. package/dist/components/draw-peaks.js +7 -0
  43. package/dist/esm/audio-waveform-worker.mjs +9 -14
  44. package/dist/esm/{chunk-261b3aa0.js → chunk-nrgs0ad5.js} +2810 -2975
  45. package/dist/esm/internals.mjs +2810 -2975
  46. package/dist/esm/previewEntry.mjs +2809 -2974
  47. package/dist/esm/renderEntry.mjs +1 -1
  48. package/dist/helpers/calculate-timeline.d.ts +3 -2
  49. package/dist/helpers/calculate-timeline.js +21 -2
  50. package/dist/helpers/get-timeline-sequence-layout.js +3 -3
  51. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +6 -1
  52. package/dist/helpers/timeline-layout.d.ts +18 -9
  53. package/dist/helpers/timeline-layout.js +24 -16
  54. package/dist/icons/Checkmark.d.ts +4 -1
  55. package/dist/icons/Checkmark.js +1 -5
  56. package/dist/icons/caret.d.ts +3 -1
  57. package/dist/icons/caret.js +5 -2
  58. package/package.json +10 -9
  59. package/dist/components/looped-media-timeline.d.ts +0 -6
  60. package/dist/components/looped-media-timeline.js +0 -14
  61. package/dist/helpers/extract-frames.d.ts +0 -18
  62. package/dist/helpers/extract-frames.js +0 -87
  63. package/dist/helpers/frame-database.d.ts +0 -16
  64. package/dist/helpers/frame-database.js +0 -65
  65. package/dist/helpers/resize-video-frame.d.ts +0 -4
  66. package/dist/helpers/resize-video-frame.js +0 -39
@@ -3,5 +3,6 @@ export declare const TimelineExpandArrowButton: React.FC<{
3
3
  readonly isExpanded: boolean;
4
4
  readonly onClick: () => void;
5
5
  readonly label: string;
6
+ readonly disabled: boolean;
6
7
  }>;
7
8
  export declare const TimelineExpandArrowSpacer: React.FC;
@@ -22,14 +22,16 @@ const arrowButton = {
22
22
  lineHeight: 1,
23
23
  };
24
24
  const svgStyle = { display: 'block' };
25
- const TimelineExpandArrowButton = ({ isExpanded, onClick, label }) => {
25
+ const TimelineExpandArrowButton = ({ isExpanded, onClick, label, disabled = false }) => {
26
26
  const style = (0, react_1.useMemo)(() => {
27
27
  return {
28
28
  ...arrowButton,
29
29
  transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',
30
+ cursor: disabled ? 'default' : 'pointer',
31
+ opacity: disabled ? 0.5 : 1,
30
32
  };
31
- }, [isExpanded]);
32
- return (jsx_runtime_1.jsx("button", { type: "button", style: style, onClick: onClick, "aria-expanded": isExpanded, "aria-label": `${isExpanded ? 'Collapse' : 'Expand'} ${label}`, children: jsx_runtime_1.jsx("svg", { width: "12", height: "12", viewBox: "0 0 8 8", style: svgStyle, children: jsx_runtime_1.jsx("path", { d: "M2 1L6 4L2 7Z", fill: "white" }) }) }));
33
+ }, [isExpanded, disabled]);
34
+ return (jsx_runtime_1.jsx("button", { type: "button", style: style, onClick: onClick, disabled: disabled, "aria-expanded": isExpanded, "aria-label": `${isExpanded ? 'Collapse' : 'Expand'} ${label}`, children: jsx_runtime_1.jsx("svg", { width: "12", height: "12", viewBox: "0 0 8 8", style: svgStyle, children: jsx_runtime_1.jsx("path", { d: "M2 1L6 4L2 7Z", fill: "white" }) }) }));
33
35
  };
34
36
  exports.TimelineExpandArrowButton = TimelineExpandArrowButton;
35
37
  const TimelineExpandArrowSpacer = () => {
@@ -1,16 +1,16 @@
1
- import type { SequenceNodePath } from '@remotion/studio-shared';
2
1
  import React from 'react';
3
- import type { SequenceSchema } from 'remotion';
2
+ import type { SequenceSchema, SequenceNodePath } from 'remotion';
4
3
  import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
4
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
5
5
  import type { TimelineTreeNode } from '../../helpers/timeline-layout';
6
+ import type { GetIsExpanded } from '../ExpandedTracksProvider';
6
7
  export declare const TimelineExpandedRow: React.FC<{
7
8
  readonly node: TimelineTreeNode;
8
9
  readonly depth: number;
9
10
  readonly nestedDepth: number;
10
- readonly expandedTracks: Record<string, boolean>;
11
- readonly toggleTrack: (id: string) => void;
12
- readonly overrideId: string;
11
+ readonly getIsExpanded: GetIsExpanded;
12
+ readonly toggleTrack: (nodePathInfo: SequenceNodePathInfo) => void;
13
13
  readonly validatedLocation: CodePosition | null;
14
- readonly nodePath: SequenceNodePath | null;
14
+ readonly nodePath: SequenceNodePath;
15
15
  readonly schema: SequenceSchema;
16
16
  }>;
@@ -24,8 +24,7 @@ const labelOnlyRowBase = {
24
24
  alignItems: 'center',
25
25
  paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
26
26
  };
27
- const TimelineExpandedRow = ({ node, depth, nestedDepth, expandedTracks, toggleTrack, overrideId, validatedLocation, nodePath, schema, }) => {
28
- var _a;
27
+ const TimelineExpandedRow = ({ node, depth, nestedDepth, getIsExpanded, toggleTrack, validatedLocation, nodePath, schema, }) => {
29
28
  const paddingLeft = timeline_layout_1.EXPANDED_SECTION_PADDING_LEFT + depth * TimelineListItem_1.INDENT;
30
29
  const groupStyle = (0, react_1.useMemo)(() => ({ ...groupRowBase, paddingLeft }), [paddingLeft]);
31
30
  const labelOnlyStyle = (0, react_1.useMemo)(() => ({
@@ -34,13 +33,13 @@ const TimelineExpandedRow = ({ node, depth, nestedDepth, expandedTracks, toggleT
34
33
  paddingLeft,
35
34
  }), [node, paddingLeft]);
36
35
  if (node.kind === 'group') {
37
- const isExpanded = (_a = expandedTracks[node.id]) !== null && _a !== void 0 ? _a : false;
36
+ const isExpanded = getIsExpanded(node.nodePathInfo);
38
37
  return (jsx_runtime_1.jsxs("div", { style: groupStyle, children: [
39
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(node.id), label: `${node.label} section` }), jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label })
38
+ jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(node.nodePathInfo), label: `${node.label} section`, disabled: false }), jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label })
40
39
  ] }));
41
40
  }
42
41
  if (node.field) {
43
- return (jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: node.field, overrideId: overrideId, validatedLocation: validatedLocation, paddingLeft: paddingLeft, nestedDepth: nestedDepth, nodePath: nodePath, schema: schema }));
42
+ return (jsx_runtime_1.jsx(TimelineFieldRow_1.TimelineFieldRow, { field: node.field, validatedLocation: validatedLocation, paddingLeft: paddingLeft, nestedDepth: nestedDepth, nodePath: nodePath, schema: schema }));
44
43
  }
45
44
  return (jsx_runtime_1.jsxs("div", { style: labelOnlyStyle, children: [
46
45
  jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("span", { style: rowLabel, children: node.label })
@@ -1,10 +1,10 @@
1
- import type { SequenceNodePath } from '@remotion/studio-shared';
2
1
  import React from 'react';
3
2
  import { type TSequence } from 'remotion';
4
3
  import type { OriginalPosition } from '../../error-overlay/react-overlay/utils/get-source-map';
4
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
5
5
  export declare const TimelineExpandedSection: React.FC<{
6
6
  readonly sequence: TSequence;
7
7
  readonly originalLocation: OriginalPosition | null;
8
- readonly nodePath: SequenceNodePath | null;
8
+ readonly nodePathInfo: SequenceNodePathInfo;
9
9
  readonly nestedDepth: number;
10
10
  }>;
@@ -53,10 +53,10 @@ const separator = {
53
53
  height: 1,
54
54
  backgroundColor: colors_1.TIMELINE_TRACK_SEPARATOR,
55
55
  };
56
- const TimelineExpandedSection = ({ sequence, originalLocation, nodePath, nestedDepth }) => {
57
- const { expandedTracks, toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksContext);
58
- const { dragOverrides, codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
59
- const { overrideId } = sequence.controls;
56
+ const TimelineExpandedSection = ({ sequence, originalLocation, nodePathInfo, nestedDepth }) => {
57
+ const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
58
+ const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
59
+ const { getDragOverrides, getCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeGettersContext);
60
60
  const validatedLocation = (0, react_1.useMemo)(() => {
61
61
  var _a;
62
62
  if (!originalLocation ||
@@ -70,9 +70,20 @@ const TimelineExpandedSection = ({ sequence, originalLocation, nodePath, nestedD
70
70
  column: (_a = originalLocation.column) !== null && _a !== void 0 ? _a : 0,
71
71
  };
72
72
  }, [originalLocation]);
73
- const tree = (0, react_1.useMemo)(() => (0, timeline_layout_1.buildTimelineTree)({ sequence, dragOverrides, codeValues }), [sequence, dragOverrides, codeValues]);
74
- const flat = (0, react_1.useMemo)(() => (0, timeline_layout_1.flattenVisibleTreeNodes)({ nodes: tree, expandedTracks }), [tree, expandedTracks]);
75
- const expandedHeight = (0, react_1.useMemo)(() => (0, timeline_layout_1.getExpandedTrackHeight)(sequence, expandedTracks, dragOverrides, codeValues), [sequence, expandedTracks, dragOverrides, codeValues]);
73
+ const tree = (0, react_1.useMemo)(() => (0, timeline_layout_1.buildTimelineTree)({
74
+ sequence,
75
+ nodePathInfo,
76
+ getDragOverrides,
77
+ getCodeValues,
78
+ }), [sequence, nodePathInfo, getDragOverrides, getCodeValues]);
79
+ const flat = (0, react_1.useMemo)(() => (0, timeline_layout_1.flattenVisibleTreeNodes)({ nodes: tree, getIsExpanded }), [tree, getIsExpanded]);
80
+ const expandedHeight = (0, react_1.useMemo)(() => (0, timeline_layout_1.getExpandedTrackHeight)({
81
+ sequence,
82
+ nodePathInfo,
83
+ getIsExpanded,
84
+ getDragOverrides,
85
+ getCodeValues,
86
+ }), [sequence, nodePathInfo, getIsExpanded, getDragOverrides, getCodeValues]);
76
87
  const style = (0, react_1.useMemo)(() => {
77
88
  return {
78
89
  ...expandedSectionBase,
@@ -84,8 +95,8 @@ const TimelineExpandedSection = ({ sequence, originalLocation, nodePath, nestedD
84
95
  return jsx_runtime_1.jsx("div", { style: style, children: "No schema" });
85
96
  }
86
97
  return (jsx_runtime_1.jsx("div", { style: style, children: flat.map(({ node, depth }, i) => {
87
- return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i > 0 ? jsx_runtime_1.jsx("div", { style: separator }) : null, jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: nestedDepth, expandedTracks: expandedTracks, toggleTrack: toggleTrack, overrideId: overrideId, validatedLocation: validatedLocation, nodePath: nodePath, schema: schema })
88
- ] }, node.id));
98
+ return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i > 0 ? jsx_runtime_1.jsx("div", { style: separator }) : null, jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: nestedDepth, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.nodePath, schema: schema })
99
+ ] }, JSON.stringify(node.nodePathInfo)));
89
100
  }) }));
90
101
  };
91
102
  exports.TimelineExpandedSection = TimelineExpandedSection;
@@ -1,14 +1,13 @@
1
- import type { SequenceNodePath } from '@remotion/studio-shared';
2
1
  import React from 'react';
2
+ import type { SequenceNodePath } from 'remotion';
3
3
  import type { SequenceSchema } from 'remotion';
4
4
  import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
5
5
  import type { SchemaFieldInfo } from '../../helpers/timeline-layout';
6
6
  export declare const TimelineFieldRow: React.FC<{
7
7
  readonly field: SchemaFieldInfo;
8
- readonly overrideId: string;
9
8
  readonly validatedLocation: CodePosition | null;
10
9
  readonly paddingLeft: number;
11
10
  readonly nestedDepth: number;
12
- readonly nodePath: SequenceNodePath | null;
11
+ readonly nodePath: SequenceNodePath;
13
12
  readonly schema: SequenceSchema;
14
13
  }>;
@@ -26,15 +26,18 @@ const fieldLabelRow = {
26
26
  alignItems: 'center',
27
27
  gap: 6,
28
28
  };
29
- const TimelineFieldRow = ({ field, overrideId, validatedLocation, paddingLeft, nestedDepth, nodePath, schema, }) => {
30
- var _a, _b, _c, _d;
31
- const { setDragOverrides, clearDragOverrides, dragOverrides, codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
32
- const codeValuesForOverride = (_a = codeValues[overrideId]) !== null && _a !== void 0 ? _a : null;
33
- const codeValue = (_b = codeValuesForOverride === null || codeValuesForOverride === void 0 ? void 0 : codeValuesForOverride[field.key]) !== null && _b !== void 0 ? _b : null;
29
+ const TimelineFieldRow = ({ field, validatedLocation, paddingLeft, nestedDepth, nodePath, schema, }) => {
30
+ var _a, _b, _c;
31
+ const { getDragOverrides, getCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeGettersContext);
32
+ const { setDragOverrides, clearDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
33
+ const codeValuesForOverride = getCodeValues(nodePath);
34
+ const codeValue = (_a = codeValuesForOverride === null || codeValuesForOverride === void 0 ? void 0 : codeValuesForOverride[field.key]) !== null && _a !== void 0 ? _a : null;
34
35
  const dragOverrideValue = (0, react_1.useMemo)(() => {
35
36
  var _a;
36
- return ((_a = dragOverrides[overrideId]) !== null && _a !== void 0 ? _a : {})[field.key];
37
- }, [dragOverrides, overrideId, field.key]);
37
+ return nodePath === null
38
+ ? undefined
39
+ : ((_a = getDragOverrides(nodePath)) !== null && _a !== void 0 ? _a : {})[field.key];
40
+ }, [getDragOverrides, nodePath, field.key]);
38
41
  const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
39
42
  codeValue,
40
43
  runtimeValue: field.currentRuntimeValue,
@@ -42,7 +45,7 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation, paddingLeft, n
42
45
  defaultValue: field.fieldSchema.default,
43
46
  shouldResortToDefaultValueIfUndefined: true,
44
47
  });
45
- const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
48
+ const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
46
49
  const onSave = (0, react_1.useCallback)((key, value) => {
47
50
  if (!codeValuesForOverride || !validatedLocation || !nodePath) {
48
51
  return Promise.reject(new Error('Cannot save'));
@@ -63,12 +66,7 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation, paddingLeft, n
63
66
  schema,
64
67
  }).then((data) => {
65
68
  if (data.success) {
66
- if (data.newStatus.canUpdate) {
67
- setCodeValues(overrideId, data.newStatus.props);
68
- }
69
- else {
70
- setCodeValues(overrideId, null);
71
- }
69
+ setCodeValues(nodePath, data.newStatus);
72
70
  return;
73
71
  }
74
72
  return Promise.reject(new Error(data.reason));
@@ -77,17 +75,22 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation, paddingLeft, n
77
75
  codeValuesForOverride,
78
76
  field.fieldSchema.default,
79
77
  nodePath,
80
- overrideId,
81
78
  schema,
82
79
  setCodeValues,
83
80
  validatedLocation,
84
81
  ]);
85
82
  const onDragValueChange = (0, react_1.useCallback)((key, value) => {
86
- setDragOverrides(overrideId, key, value);
87
- }, [setDragOverrides, overrideId]);
83
+ if (nodePath === null) {
84
+ throw new Error('Cannot drag value');
85
+ }
86
+ setDragOverrides(nodePath, key, value);
87
+ }, [setDragOverrides, nodePath]);
88
88
  const onDragEnd = (0, react_1.useCallback)(() => {
89
- clearDragOverrides(overrideId);
90
- }, [clearDragOverrides, overrideId]);
89
+ if (nodePath === null) {
90
+ throw new Error('Cannot clear drag value');
91
+ }
92
+ clearDragOverrides(nodePath);
93
+ }, [clearDragOverrides, nodePath]);
91
94
  const style = (0, react_1.useMemo)(() => {
92
95
  return {
93
96
  ...fieldRowBase,
@@ -96,7 +99,7 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation, paddingLeft, n
96
99
  };
97
100
  }, [field.rowHeight, paddingLeft]);
98
101
  return (jsx_runtime_1.jsxs("div", { style: style, children: [
99
- jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_c = field.description) !== null && _c !== void 0 ? _c : field.key }) }), jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: codeValue, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, canUpdate: (_d = codeValue === null || codeValue === void 0 ? void 0 : codeValue.canUpdate) !== null && _d !== void 0 ? _d : false, effectiveValue: effectiveValue, codeValue: codeValue })
102
+ jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_b = field.description) !== null && _b !== void 0 ? _b : field.key }) }), jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: codeValue, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, canUpdate: (_c = codeValue === null || codeValue === void 0 ? void 0 : codeValue.canUpdate) !== null && _c !== void 0 ? _c : false, effectiveValue: effectiveValue, codeValue: codeValue })
100
103
  ] }));
101
104
  };
102
105
  exports.TimelineFieldRow = TimelineFieldRow;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { TrackWithHash } from '../../helpers/get-timeline-sequence-sort-key';
3
+ export declare const TimelineHeightContainer: React.FC<{
4
+ readonly shown: TrackWithHash[];
5
+ readonly hasBeenCut: boolean;
6
+ readonly children: React.ReactNode;
7
+ }>;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineHeightContainer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const use_timeline_height_1 = require("./use-timeline-height");
7
+ const baseStyle = {
8
+ display: 'flex',
9
+ flex: 1,
10
+ minHeight: '100%',
11
+ overflowX: 'hidden',
12
+ };
13
+ const TimelineHeightContainer = ({ shown, hasBeenCut, children }) => {
14
+ const height = (0, use_timeline_height_1.useTimelineHeight)({ shown, hasBeenCut });
15
+ const style = (0, react_1.useMemo)(() => ({ ...baseStyle, height }), [height]);
16
+ return jsx_runtime_1.jsx("div", { style: style, children: children });
17
+ };
18
+ exports.TimelineHeightContainer = TimelineHeightContainer;
@@ -20,7 +20,7 @@ const TimelineList = ({ timeline }) => {
20
20
  const isCompact = size ? size.width < 250 : false;
21
21
  return (jsx_runtime_1.jsxs("div", { ref: ref, style: container, children: [
22
22
  jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), timeline.map((track) => {
23
- return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineListItem_1.TimelineListItem, { nestedDepth: track.depth, sequence: track.sequence, isCompact: isCompact }, track.sequence.id) }, track.sequence.id));
23
+ return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineListItem_1.TimelineListItem, { nestedDepth: track.depth, sequence: track.sequence, isCompact: isCompact, nodePathInfo: track.nodePathInfo }, track.sequence.id) }, track.sequence.id));
24
24
  })] }));
25
25
  };
26
26
  exports.TimelineList = TimelineList;
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
  import type { TSequence } from 'remotion';
3
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
4
  export declare const INDENT = 10;
4
5
  export declare const TimelineListItem: React.FC<{
5
6
  readonly sequence: TSequence;
6
7
  readonly nestedDepth: number;
7
8
  readonly isCompact: boolean;
9
+ readonly nodePathInfo: SequenceNodePathInfo | null;
8
10
  }>;
@@ -17,18 +17,19 @@ const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
17
17
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
18
18
  const TimelineStack_1 = require("./TimelineStack");
19
19
  const use_resolved_stack_1 = require("./use-resolved-stack");
20
- const use_sequence_props_subscription_1 = require("./use-sequence-props-subscription");
21
20
  exports.INDENT = 10;
22
- const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
21
+ const TimelineListItem = ({ nestedDepth, sequence, isCompact, nodePathInfo }) => {
23
22
  var _a, _b;
23
+ const nodePath = (_a = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.nodePath) !== null && _a !== void 0 ? _a : null;
24
24
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
25
25
  const visualModeEnvEnabled = Boolean(process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED);
26
26
  const previewConnected = previewServerState.type === 'connected';
27
27
  const visualModeActive = visualModeEnvEnabled && previewConnected;
28
28
  const { hidden, setHidden } = (0, react_1.useContext)(remotion_1.Internals.SequenceVisibilityToggleContext);
29
- const { expandedTracks, toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksContext);
30
- const originalLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = sequence.stack) !== null && _a !== void 0 ? _a : null);
31
- const { nodePath, jsxInMapCallback } = (0, use_sequence_props_subscription_1.useSequencePropsSubscription)(sequence, originalLocation, visualModeActive);
29
+ const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
30
+ const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
31
+ const { getIsJsxInMapCallback } = (0, react_1.useContext)(remotion_1.Internals.VisualModeGettersContext);
32
+ const originalLocation = (0, use_resolved_stack_1.useResolvedStack)((_b = sequence.stack) !== null && _b !== void 0 ? _b : null);
32
33
  const validatedLocation = (0, react_1.useMemo)(() => {
33
34
  var _a;
34
35
  if (!originalLocation ||
@@ -49,7 +50,7 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
49
50
  if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
50
51
  return;
51
52
  }
52
- if (jsxInMapCallback) {
53
+ if (getIsJsxInMapCallback(nodePath)) {
53
54
  const message = 'This sequence is rendered inside a .map() callback. Duplicating inserts another copy in that callback (affecting each list item). Continue?';
54
55
  // eslint-disable-next-line no-alert -- native confirm before applying duplicate codemod in .map callbacks
55
56
  if (!window.confirm(message)) {
@@ -71,11 +72,18 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
71
72
  catch (err) {
72
73
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
73
74
  }
74
- }, [jsxInMapCallback, nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
75
+ }, [nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source, getIsJsxInMapCallback]);
75
76
  const onDeleteSequenceFromSource = (0, react_1.useCallback)(async () => {
76
77
  if (!(validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source) || !nodePath) {
77
78
  return;
78
79
  }
80
+ if (getIsJsxInMapCallback(nodePath)) {
81
+ const message = 'This sequence is rendered inside a .map() callback. Deleting removes all sequences in that callback. Continue?';
82
+ // eslint-disable-next-line no-alert -- native confirm before applying duplicate codemod in .map callbacks
83
+ if (!window.confirm(message)) {
84
+ return;
85
+ }
86
+ }
79
87
  try {
80
88
  const result = await (0, call_api_1.callApi)('/api/delete-jsx-node', {
81
89
  fileName: validatedLocation.source,
@@ -91,7 +99,7 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
91
99
  catch (err) {
92
100
  (0, NotificationCenter_1.showNotification)(err.message, 4000);
93
101
  }
94
- }, [nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source]);
102
+ }, [nodePath, validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source, getIsJsxInMapCallback]);
95
103
  const contextMenuValues = (0, react_1.useMemo)(() => {
96
104
  if (!visualModeEnvEnabled) {
97
105
  return [];
@@ -139,10 +147,13 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
139
147
  onDuplicateSequenceFromSource,
140
148
  visualModeEnvEnabled,
141
149
  ]);
142
- const isExpanded = visualModeActive && ((_b = expandedTracks[sequence.id]) !== null && _b !== void 0 ? _b : false);
150
+ const isExpanded = visualModeActive && nodePathInfo !== null && getIsExpanded(nodePathInfo);
143
151
  const onToggleExpand = (0, react_1.useCallback)(() => {
144
- toggleTrack(sequence.id);
145
- }, [sequence.id, toggleTrack]);
152
+ if (nodePathInfo === null) {
153
+ return;
154
+ }
155
+ toggleTrack(nodePathInfo);
156
+ }, [nodePathInfo, toggleTrack]);
146
157
  const isItemHidden = (0, react_1.useMemo)(() => {
147
158
  var _a;
148
159
  return (_a = hidden[sequence.id]) !== null && _a !== void 0 ? _a : false;
@@ -177,8 +188,11 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
177
188
  }, []);
178
189
  const hasExpandableContent = Boolean(sequence.controls) || sequence.effects.length > 0;
179
190
  const trackRow = (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsxs("div", { style: inner, children: [
180
- jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility }), jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth }), visualModeActive ? (hasExpandableContent ? (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: onToggleExpand, label: "track properties" })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}))) : null, jsx_runtime_1.jsx(TimelineStack_1.TimelineStack, { sequence: sequence, isCompact: isCompact, originalLocation: originalLocation })
191
+ jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility }), jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth }), visualModeActive ? (hasExpandableContent ? (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: onToggleExpand, label: "track properties", disabled: nodePathInfo === null })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}))) : null, jsx_runtime_1.jsx(TimelineStack_1.TimelineStack, { sequence: sequence, isCompact: isCompact, originalLocation: originalLocation })
181
192
  ] }) }));
182
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [visualModeEnvEnabled ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, children: trackRow })) : (trackRow), visualModeActive && isExpanded && hasExpandableContent ? (jsx_runtime_1.jsx(TimelineExpandedSection_1.TimelineExpandedSection, { sequence: sequence, originalLocation: originalLocation, nodePath: nodePath, nestedDepth: nestedDepth })) : null] }));
193
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [visualModeEnvEnabled ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, children: trackRow })) : (trackRow), visualModeActive &&
194
+ isExpanded &&
195
+ hasExpandableContent &&
196
+ nodePathInfo ? (jsx_runtime_1.jsx(TimelineExpandedSection_1.TimelineExpandedSection, { sequence: sequence, originalLocation: originalLocation, nodePathInfo: nodePathInfo, nestedDepth: nestedDepth })) : null] }));
183
197
  };
184
198
  exports.TimelineListItem = TimelineListItem;
@@ -17,6 +17,9 @@ const notEditableBackground = {
17
17
  borderRadius: 3,
18
18
  padding: '0 4px',
19
19
  };
20
+ const inlineWrapper = {
21
+ fontSize: 12,
22
+ };
20
23
  const TimelineFieldValue = ({ field, onSave, onDragValueChange, onDragEnd, propStatus, canUpdate, effectiveValue, codeValue, }) => {
21
24
  const wrapperStyle = canUpdate === null || canUpdate === false
22
25
  ? notEditableBackground
@@ -46,7 +49,7 @@ const TimelineFieldValue = ({ field, onSave, onDragValueChange, onDragEnd, propS
46
49
  return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineBooleanField_1.TimelineBooleanField, { field: field, codeValue: codeValue, canUpdate: canUpdate, onSave: onSave, effectiveValue: effectiveValue }) }));
47
50
  }
48
51
  if (field.typeName === 'enum') {
49
- return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineEnumField_1.TimelineEnumField, { field: field, codeValue: codeValue, canUpdate: canUpdate, onSave: onSave, effectiveValue: effectiveValue, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd }) }));
52
+ return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineEnumField_1.TimelineEnumField, { field: field, codeValue: codeValue, canUpdate: canUpdate, onSave: onSave, effectiveValue: effectiveValue, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd }) }));
50
53
  }
51
54
  return (jsx_runtime_1.jsx("span", { style: { ...unsupportedLabel, fontStyle: 'normal' }, children: String(effectiveValue) }));
52
55
  };
@@ -19,13 +19,19 @@ const content = {
19
19
  const timelineContent = {
20
20
  minHeight: '100%',
21
21
  };
22
- const getExpandedPlaceholderStyle = (sequence, expandedTracks, dragOverrides, codeValues) => ({
23
- height: (0, timeline_layout_1.getExpandedTrackHeight)(sequence, expandedTracks, dragOverrides, codeValues) + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
22
+ const getExpandedPlaceholderStyle = ({ sequence, nodePathInfo, getIsExpanded, getDragOverrides, getCodeValues, }) => ({
23
+ height: (0, timeline_layout_1.getExpandedTrackHeight)({
24
+ sequence,
25
+ nodePathInfo,
26
+ getIsExpanded,
27
+ getDragOverrides,
28
+ getCodeValues,
29
+ }) + timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
24
30
  });
25
31
  const TimelineTracks = ({ timeline, hasBeenCut }) => {
26
- const { expandedTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksContext);
32
+ const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
27
33
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
28
- const { dragOverrides, codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
34
+ const { getDragOverrides, getCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeGettersContext);
29
35
  const visualModeEnabled = Boolean(process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED) &&
30
36
  previewServerState.type === 'connected';
31
37
  const timelineStyle = (0, react_1.useMemo)(() => {
@@ -37,16 +43,21 @@ const TimelineTracks = ({ timeline, hasBeenCut }) => {
37
43
  return (jsx_runtime_1.jsxs("div", { style: timelineStyle, children: [
38
44
  jsx_runtime_1.jsxs("div", { style: content, children: [
39
45
  jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), timeline.map((track) => {
40
- var _a;
41
46
  if ((0, is_collapsed_1.isTrackHidden)(track)) {
42
47
  return null;
43
48
  }
44
- const isExpanded = (_a = expandedTracks[track.sequence.id]) !== null && _a !== void 0 ? _a : false;
49
+ const isExpanded = track.nodePathInfo !== null && getIsExpanded(track.nodePathInfo);
45
50
  return (jsx_runtime_1.jsxs("div", { children: [
46
51
  jsx_runtime_1.jsx("div", { style: {
47
52
  height: (0, timeline_layout_1.getTimelineLayerHeight)(track.sequence.type),
48
53
  marginBottom: timeline_layout_1.TIMELINE_ITEM_BORDER_BOTTOM,
49
- }, children: jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence }) }), visualModeEnabled && isExpanded ? (jsx_runtime_1.jsx("div", { style: getExpandedPlaceholderStyle(track.sequence, expandedTracks, dragOverrides, codeValues) })) : null] }, track.sequence.id));
54
+ }, children: jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence }) }), visualModeEnabled && isExpanded && track.nodePathInfo ? (jsx_runtime_1.jsx("div", { style: getExpandedPlaceholderStyle({
55
+ sequence: track.sequence,
56
+ nodePathInfo: track.nodePathInfo,
57
+ getIsExpanded,
58
+ getDragOverrides,
59
+ getCodeValues,
60
+ }) })) : null] }, track.sequence.id));
50
61
  })] }), hasBeenCut ? jsx_runtime_1.jsx(MaxTimelineTracks_1.MaxTimelineTracksReached, {}) : null] }));
51
62
  };
52
63
  exports.TimelineTracks = TimelineTracks;