@remotion/studio 4.0.484 → 4.0.485

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 (76) hide show
  1. package/dist/components/ContextMenu.js +75 -1
  2. package/dist/components/CurrentComposition.js +3 -2
  3. package/dist/components/InlineCompositionName.d.ts +7 -0
  4. package/dist/components/InlineCompositionName.js +58 -0
  5. package/dist/components/InlineEditableTitle.d.ts +7 -0
  6. package/dist/components/InlineEditableTitle.js +129 -0
  7. package/dist/components/InspectorPanel/KeyframeInspector.js +1 -0
  8. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +17 -30
  9. package/dist/components/InspectorPanel/styles.js +2 -2
  10. package/dist/components/InspectorSequenceSection.js +34 -1
  11. package/dist/components/Modals.js +1 -1
  12. package/dist/components/NewComposition/CodemodFooter.d.ts +7 -1
  13. package/dist/components/NewComposition/CodemodFooter.js +17 -12
  14. package/dist/components/NewComposition/DeleteComposition.js +7 -1
  15. package/dist/components/NewComposition/DeleteFolder.js +7 -1
  16. package/dist/components/NewComposition/DuplicateComposition.js +17 -10
  17. package/dist/components/NewComposition/InputAndValidationContainer.d.ts +3 -0
  18. package/dist/components/NewComposition/InputAndValidationContainer.js +15 -0
  19. package/dist/components/NewComposition/NewCompDuration.js +7 -6
  20. package/dist/components/NewComposition/NewComposition.d.ts +5 -1
  21. package/dist/components/NewComposition/NewComposition.js +29 -86
  22. package/dist/components/NewComposition/RenameComposition.js +13 -14
  23. package/dist/components/NewComposition/RenameFolder.js +9 -2
  24. package/dist/components/NewComposition/RenameStaticFile.js +2 -1
  25. package/dist/components/NewComposition/ValidationMessage.js +9 -1
  26. package/dist/components/OptionsPanel.d.ts +0 -3
  27. package/dist/components/OptionsPanel.js +7 -3
  28. package/dist/components/RenderModal/ServerRenderModal.js +4 -3
  29. package/dist/components/RenderModal/WebRenderModal.js +2 -1
  30. package/dist/components/SelectedOutlineElement.js +45 -3
  31. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  32. package/dist/components/SelectedOutlineOverlay.js +15 -3
  33. package/dist/components/Timeline/TimelineDeleteKeybindings.js +34 -1
  34. package/dist/components/Timeline/TimelineExpandedSection.js +1 -0
  35. package/dist/components/Timeline/TimelineInOutPointerHandle.js +2 -1
  36. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -1
  37. package/dist/components/Timeline/TimelineKeyframeControls.js +1 -0
  38. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  39. package/dist/components/Timeline/TimelineSelection.js +1 -0
  40. package/dist/components/Timeline/TimelineSequenceItem.js +19 -101
  41. package/dist/components/Timeline/TimelineSequencePropItem.js +6 -3
  42. package/dist/components/Timeline/TimelineTextContentField.d.ts +12 -0
  43. package/dist/components/Timeline/TimelineTextContentField.js +100 -0
  44. package/dist/components/Timeline/TimelineWidthProvider.js +18 -3
  45. package/dist/components/Timeline/focus-inspector-field.d.ts +16 -0
  46. package/dist/components/Timeline/focus-inspector-field.js +49 -0
  47. package/dist/components/Timeline/split-selected-timeline-item.d.ts +38 -0
  48. package/dist/components/Timeline/split-selected-timeline-item.js +156 -0
  49. package/dist/components/Timeline/timeline-field-display-utils.js +2 -0
  50. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +1 -0
  51. package/dist/components/Timeline/use-rename-sequence.d.ts +30 -0
  52. package/dist/components/Timeline/use-rename-sequence.js +115 -0
  53. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  54. package/dist/components/Timeline/use-timeline-expanded-tree.js +3 -1
  55. package/dist/components/Timeline/use-timeline-height.js +1 -0
  56. package/dist/components/composition-menu-items.js +3 -0
  57. package/dist/components/folder-menu-items.js +20 -0
  58. package/dist/components/options-sidebar-tabs.d.ts +4 -0
  59. package/dist/components/options-sidebar-tabs.js +5 -0
  60. package/dist/components/selected-outline-types.d.ts +6 -1
  61. package/dist/esm/{chunk-9erwh79m.js → chunk-103pp4n7.js} +6734 -5683
  62. package/dist/esm/internals.mjs +6734 -5683
  63. package/dist/esm/previewEntry.mjs +6649 -5598
  64. package/dist/esm/renderEntry.mjs +1 -1
  65. package/dist/helpers/render-codec-label.d.ts +1 -1
  66. package/dist/helpers/timeline-layout.d.ts +4 -3
  67. package/dist/helpers/timeline-layout.js +3 -1
  68. package/dist/helpers/use-create-composition.d.ts +35 -0
  69. package/dist/helpers/use-create-composition.js +111 -0
  70. package/dist/helpers/use-rename-composition.d.ts +16 -0
  71. package/dist/helpers/use-rename-composition.js +49 -0
  72. package/dist/state/modals.d.ts +3 -0
  73. package/dist/state/timeline-zoom.js +17 -14
  74. package/dist/state/z-index.d.ts +1 -0
  75. package/dist/state/z-index.js +11 -2
  76. package/package.json +12 -12
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineTextContentField = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const RemTextarea_1 = require("../NewComposition/RemTextarea");
7
+ const focus_inspector_field_1 = require("./focus-inspector-field");
8
+ const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd, onDragValueChange, onSave, propStatus, }) => {
9
+ var _a;
10
+ const inputRef = (0, react_1.useRef)(null);
11
+ const currentValue = String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '');
12
+ const draftRef = (0, react_1.useRef)({
13
+ dirty: false,
14
+ value: currentValue,
15
+ });
16
+ const latestRef = (0, react_1.useRef)({
17
+ codeValue: propStatus.codeValue,
18
+ onDragEnd,
19
+ onDragValueChange,
20
+ onSave,
21
+ });
22
+ latestRef.current = {
23
+ codeValue: propStatus.codeValue,
24
+ onDragEnd,
25
+ onDragValueChange,
26
+ onSave,
27
+ };
28
+ if (!draftRef.current.dirty) {
29
+ draftRef.current.value = currentValue;
30
+ }
31
+ const commitPending = (0, react_1.useCallback)(() => {
32
+ var _a;
33
+ var _b, _c;
34
+ if (!draftRef.current.dirty) {
35
+ return false;
36
+ }
37
+ const value = (_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : draftRef.current.value;
38
+ const savedValue = String((_c = latestRef.current.codeValue) !== null && _c !== void 0 ? _c : '');
39
+ draftRef.current = {
40
+ dirty: false,
41
+ value,
42
+ };
43
+ if (value === savedValue) {
44
+ latestRef.current.onDragEnd();
45
+ return false;
46
+ }
47
+ latestRef.current
48
+ .onSave(value)
49
+ .finally(() => {
50
+ if (!draftRef.current.dirty && draftRef.current.value === value) {
51
+ latestRef.current.onDragEnd();
52
+ }
53
+ })
54
+ .catch(() => undefined);
55
+ return true;
56
+ }, []);
57
+ const setInputRef = (0, react_1.useCallback)((element) => {
58
+ if (element === null && inputRef.current !== null) {
59
+ commitPending();
60
+ }
61
+ inputRef.current = element;
62
+ (0, focus_inspector_field_1.registerFocusInspectorFieldElement)({
63
+ element,
64
+ fieldKey: field.key,
65
+ nodePath,
66
+ });
67
+ (0, focus_inspector_field_1.registerCommitPendingInspectorField)({
68
+ commitPending: element === null ? null : commitPending,
69
+ fieldKey: field.key,
70
+ nodePath,
71
+ });
72
+ }, [commitPending, field.key, nodePath]);
73
+ const onChange = (0, react_1.useCallback)((event) => {
74
+ const { value } = event.currentTarget;
75
+ draftRef.current = {
76
+ dirty: true,
77
+ value,
78
+ };
79
+ latestRef.current.onDragValueChange(value);
80
+ }, []);
81
+ const onKeyDownCapture = (0, react_1.useCallback)((event) => {
82
+ var _a;
83
+ if (event.key === 'Escape') {
84
+ const savedValue = String((_a = latestRef.current.codeValue) !== null && _a !== void 0 ? _a : '');
85
+ draftRef.current = {
86
+ dirty: false,
87
+ value: savedValue,
88
+ };
89
+ event.currentTarget.value = savedValue;
90
+ latestRef.current.onDragEnd();
91
+ event.currentTarget.blur();
92
+ }
93
+ }, []);
94
+ return (jsx_runtime_1.jsx(RemTextarea_1.RemTextarea, { ref: setInputRef, status: "ok", small: true, defaultValue: currentValue, onBlur: commitPending, onChange: onChange, onKeyDownCapture: onKeyDownCapture, style: {
95
+ boxSizing: 'border-box',
96
+ height: 40,
97
+ width: 160,
98
+ } }, String((_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : '')));
99
+ };
100
+ exports.TimelineTextContentField = TimelineTextContentField;
@@ -4,14 +4,29 @@ exports.TimelineWidthProvider = exports.TimelineWidthContext = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const player_1 = require("@remotion/player");
6
6
  const react_1 = require("react");
7
+ const remotion_1 = require("remotion");
8
+ const timeline_zoom_1 = require("../../state/timeline-zoom");
7
9
  const timeline_refs_1 = require("./timeline-refs");
8
10
  exports.TimelineWidthContext = (0, react_1.createContext)(null);
9
11
  const TimelineWidthProvider = ({ children }) => {
10
- var _a;
11
- const size = player_1.PlayerInternals.useElementSize(timeline_refs_1.sliderAreaRef, {
12
+ const size = player_1.PlayerInternals.useElementSize(timeline_refs_1.scrollableRef, {
12
13
  triggerOnWindowResize: false,
13
14
  shouldApplyCssTransforms: true,
14
15
  });
15
- return (jsx_runtime_1.jsx(exports.TimelineWidthContext.Provider, { value: (_a = size === null || size === void 0 ? void 0 : size.width) !== null && _a !== void 0 ? _a : null, children: children }));
16
+ const { zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
17
+ const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
18
+ const width = (0, react_1.useMemo)(() => {
19
+ var _a, _b;
20
+ var _c, _d, _e;
21
+ const zoom = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition'
22
+ ? ((_c = zoomMap[canvasContent.compositionId]) !== null && _c !== void 0 ? _c : timeline_zoom_1.TIMELINE_MIN_ZOOM)
23
+ : timeline_zoom_1.TIMELINE_MIN_ZOOM;
24
+ const scrollableWidth = (_d = size === null || size === void 0 ? void 0 : size.width) !== null && _d !== void 0 ? _d : (_a = timeline_refs_1.scrollableRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth;
25
+ if (scrollableWidth === undefined) {
26
+ return (_e = (_b = timeline_refs_1.sliderAreaRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) !== null && _e !== void 0 ? _e : null;
27
+ }
28
+ return scrollableWidth * zoom;
29
+ }, [canvasContent, size === null || size === void 0 ? void 0 : size.width, zoomMap]);
30
+ return (jsx_runtime_1.jsx(exports.TimelineWidthContext.Provider, { value: width, children: children }));
16
31
  };
17
32
  exports.TimelineWidthProvider = TimelineWidthProvider;
@@ -0,0 +1,16 @@
1
+ import type { SequencePropsSubscriptionKey } from 'remotion';
2
+ export declare const registerFocusInspectorFieldElement: ({ element, fieldKey, nodePath, }: {
3
+ readonly element: HTMLTextAreaElement | null;
4
+ readonly fieldKey: string;
5
+ readonly nodePath: SequencePropsSubscriptionKey | null;
6
+ }) => void;
7
+ export declare const requestFocusInspectorField: ({ fieldKey, nodePath, }: {
8
+ readonly fieldKey: string;
9
+ readonly nodePath: SequencePropsSubscriptionKey;
10
+ }) => void;
11
+ export declare const registerCommitPendingInspectorField: ({ commitPending, fieldKey, nodePath, }: {
12
+ readonly commitPending: (() => boolean) | null;
13
+ readonly fieldKey: string;
14
+ readonly nodePath: SequencePropsSubscriptionKey | null;
15
+ }) => void;
16
+ export declare const commitPendingInspectorFields: () => boolean;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commitPendingInspectorFields = exports.registerCommitPendingInspectorField = exports.requestFocusInspectorField = exports.registerFocusInspectorFieldElement = void 0;
4
+ const serializeRegistryKey = ({ fieldKey, nodePath, }) => {
5
+ return JSON.stringify({ fieldKey, nodePath });
6
+ };
7
+ const registeredFields = new Map();
8
+ const registeredCommitPendingCallbacks = new Map();
9
+ const registerFocusInspectorFieldElement = ({ element, fieldKey, nodePath, }) => {
10
+ if (nodePath === null) {
11
+ return;
12
+ }
13
+ const key = serializeRegistryKey({ fieldKey, nodePath });
14
+ if (element === null) {
15
+ registeredFields.delete(key);
16
+ return;
17
+ }
18
+ registeredFields.set(key, element);
19
+ };
20
+ exports.registerFocusInspectorFieldElement = registerFocusInspectorFieldElement;
21
+ const requestFocusInspectorField = ({ fieldKey, nodePath, }) => {
22
+ const element = registeredFields.get(serializeRegistryKey({ fieldKey, nodePath }));
23
+ requestAnimationFrame(() => {
24
+ element === null || element === void 0 ? void 0 : element.scrollIntoView({ block: 'center' });
25
+ element === null || element === void 0 ? void 0 : element.focus();
26
+ element === null || element === void 0 ? void 0 : element.select();
27
+ });
28
+ };
29
+ exports.requestFocusInspectorField = requestFocusInspectorField;
30
+ const registerCommitPendingInspectorField = ({ commitPending, fieldKey, nodePath, }) => {
31
+ if (nodePath === null) {
32
+ return;
33
+ }
34
+ const key = serializeRegistryKey({ fieldKey, nodePath });
35
+ if (commitPending === null) {
36
+ registeredCommitPendingCallbacks.delete(key);
37
+ return;
38
+ }
39
+ registeredCommitPendingCallbacks.set(key, commitPending);
40
+ };
41
+ exports.registerCommitPendingInspectorField = registerCommitPendingInspectorField;
42
+ const commitPendingInspectorFields = () => {
43
+ let committed = false;
44
+ for (const commitPending of registeredCommitPendingCallbacks.values()) {
45
+ committed = commitPending() || committed;
46
+ }
47
+ return committed;
48
+ };
49
+ exports.commitPendingInspectorFields = commitPendingInspectorFields;
@@ -0,0 +1,38 @@
1
+ import type { CanUpdateSequencePropStatus, OverrideIdToNodePaths, PropStatuses, TSequence } from 'remotion';
2
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
+ import type { TimelineSelection } from './TimelineSelection';
4
+ export type SplitTimelineSequenceEligibility = {
5
+ canSplit: true;
6
+ nodePathInfo: SequenceNodePathInfo;
7
+ } | {
8
+ canSplit: false;
9
+ reason: string;
10
+ };
11
+ export declare const getTimelineSequenceSplitUnsupportedReason: (componentName: string | null | undefined) => string | null;
12
+ export declare const getTimelineSequenceSplitEligibility: ({ selection, sequence, splitFrame, propStatuses, }: {
13
+ selection: TimelineSelection;
14
+ sequence: TSequence | null;
15
+ splitFrame: number;
16
+ propStatuses?: Partial<Record<"durationInFrames" | "from" | "trimBefore", CanUpdateSequencePropStatus>> | undefined;
17
+ }) => SplitTimelineSequenceEligibility;
18
+ export declare const splitTimelineSequenceFromSource: ({ nodePathInfo, splitFrame, }: {
19
+ nodePathInfo: SequenceNodePathInfo;
20
+ splitFrame: number;
21
+ }) => Promise<boolean>;
22
+ export declare const shouldHandleTimelineDuplicateShortcut: ({ shiftKey, }: {
23
+ readonly shiftKey: boolean;
24
+ }) => boolean;
25
+ export declare const shouldHandleTimelineSplitShortcut: ({ shiftKey, }: {
26
+ readonly shiftKey: boolean;
27
+ }) => boolean;
28
+ export declare const splitSelectedTimelineItems: ({ selections, sequences, overrideIdsToNodePaths, propStatuses, splitFrame, splitSequence, }: {
29
+ selections: readonly TimelineSelection[];
30
+ sequences: TSequence[];
31
+ overrideIdsToNodePaths: OverrideIdToNodePaths;
32
+ propStatuses: PropStatuses | undefined;
33
+ splitFrame: number;
34
+ splitSequence?: ((options: {
35
+ nodePathInfo: SequenceNodePathInfo;
36
+ splitFrame: number;
37
+ }) => Promise<boolean>) | undefined;
38
+ }) => Promise<boolean> | null;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.splitSelectedTimelineItems = exports.shouldHandleTimelineSplitShortcut = exports.shouldHandleTimelineDuplicateShortcut = exports.splitTimelineSequenceFromSource = exports.getTimelineSequenceSplitEligibility = exports.getTimelineSequenceSplitUnsupportedReason = void 0;
4
+ const remotion_1 = require("remotion");
5
+ const call_api_1 = require("../call-api");
6
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
7
+ const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
8
+ const getTimelineSequenceSplitUnsupportedReason = (componentName) => {
9
+ if (componentName === '<TransitionSeries.Sequence>' ||
10
+ componentName === '<TransitionSeries.Overlay>') {
11
+ return `${componentName} cannot be split from source`;
12
+ }
13
+ return null;
14
+ };
15
+ exports.getTimelineSequenceSplitUnsupportedReason = getTimelineSequenceSplitUnsupportedReason;
16
+ const staticNumberish = (status) => {
17
+ if (!status) {
18
+ return true;
19
+ }
20
+ return (status.status === 'static' &&
21
+ (typeof status.codeValue === 'number' || status.codeValue === undefined));
22
+ };
23
+ const getTimelineSequenceSplitEligibility = ({ selection, sequence, splitFrame, propStatuses, }) => {
24
+ var _a;
25
+ if (selection.type !== 'sequence') {
26
+ return {
27
+ canSplit: false,
28
+ reason: 'Select one sequence to split',
29
+ };
30
+ }
31
+ if (!sequence) {
32
+ return {
33
+ canSplit: false,
34
+ reason: 'Could not find selected sequence',
35
+ };
36
+ }
37
+ if (!Number.isInteger(splitFrame)) {
38
+ return {
39
+ canSplit: false,
40
+ reason: 'Split frame must be an integer',
41
+ };
42
+ }
43
+ if (sequence.isInsideSeries) {
44
+ return {
45
+ canSplit: false,
46
+ reason: 'Series.Sequence clips cannot be split from source',
47
+ };
48
+ }
49
+ const unsupportedReason = (0, exports.getTimelineSequenceSplitUnsupportedReason)((_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.componentName);
50
+ if (unsupportedReason) {
51
+ return {
52
+ canSplit: false,
53
+ reason: unsupportedReason,
54
+ };
55
+ }
56
+ const { nodePathInfo } = selection;
57
+ if (!nodePathInfo.sequenceSubscriptionKey.nodePath) {
58
+ return {
59
+ canSplit: false,
60
+ reason: 'Sequence has no editable source node',
61
+ };
62
+ }
63
+ if (nodePathInfo.numberOfSequencesWithThisNodePath > 1) {
64
+ return {
65
+ canSplit: false,
66
+ reason: 'Programmatically duplicated sequences cannot be split',
67
+ };
68
+ }
69
+ if (!staticNumberish(propStatuses === null || propStatuses === void 0 ? void 0 : propStatuses.from) ||
70
+ !staticNumberish(propStatuses === null || propStatuses === void 0 ? void 0 : propStatuses.durationInFrames) ||
71
+ !staticNumberish(propStatuses === null || propStatuses === void 0 ? void 0 : propStatuses.trimBefore)) {
72
+ return {
73
+ canSplit: false,
74
+ reason: 'Sequence timing props must be static numbers',
75
+ };
76
+ }
77
+ const start = sequence.from;
78
+ const end = sequence.duration === Infinity
79
+ ? Infinity
80
+ : sequence.from + sequence.duration;
81
+ if (splitFrame <= start) {
82
+ return {
83
+ canSplit: false,
84
+ reason: 'Cannot split at the sequence start',
85
+ };
86
+ }
87
+ if (splitFrame >= end) {
88
+ return {
89
+ canSplit: false,
90
+ reason: 'Cannot split at the sequence end',
91
+ };
92
+ }
93
+ return {
94
+ canSplit: true,
95
+ nodePathInfo,
96
+ };
97
+ };
98
+ exports.getTimelineSequenceSplitEligibility = getTimelineSequenceSplitEligibility;
99
+ const splitTimelineSequenceFromSource = ({ nodePathInfo, splitFrame, }) => {
100
+ const nodePath = nodePathInfo.sequenceSubscriptionKey;
101
+ return (0, call_api_1.callApi)('/api/split-jsx-sequence', {
102
+ fileName: nodePath.absolutePath,
103
+ nodePath: nodePath.nodePath,
104
+ splitFrame,
105
+ })
106
+ .then((result) => {
107
+ if (result.success) {
108
+ (0, NotificationCenter_1.showNotification)('Split sequence', 2000);
109
+ return true;
110
+ }
111
+ (0, NotificationCenter_1.showNotification)(result.reason, 4000);
112
+ return false;
113
+ })
114
+ .catch((err) => {
115
+ (0, NotificationCenter_1.showNotification)(err.message, 4000);
116
+ return false;
117
+ });
118
+ };
119
+ exports.splitTimelineSequenceFromSource = splitTimelineSequenceFromSource;
120
+ const shouldHandleTimelineDuplicateShortcut = ({ shiftKey, }) => !shiftKey;
121
+ exports.shouldHandleTimelineDuplicateShortcut = shouldHandleTimelineDuplicateShortcut;
122
+ const shouldHandleTimelineSplitShortcut = ({ shiftKey, }) => shiftKey;
123
+ exports.shouldHandleTimelineSplitShortcut = shouldHandleTimelineSplitShortcut;
124
+ const splitSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodePaths, propStatuses, splitFrame, splitSequence = exports.splitTimelineSequenceFromSource, }) => {
125
+ var _a;
126
+ if (selections.length !== 1) {
127
+ return null;
128
+ }
129
+ const [selection] = selections;
130
+ if (selection.type !== 'sequence') {
131
+ return null;
132
+ }
133
+ const track = (0, find_track_for_node_path_info_1.findTrackForNodePathInfo)({
134
+ sequences,
135
+ overrideIdsToNodePaths,
136
+ nodePathInfo: selection.nodePathInfo,
137
+ });
138
+ const sequencePropStatuses = propStatuses
139
+ ? remotion_1.Internals.getPropStatusesCtx(propStatuses, selection.nodePathInfo.sequenceSubscriptionKey)
140
+ : undefined;
141
+ const eligibility = (0, exports.getTimelineSequenceSplitEligibility)({
142
+ selection,
143
+ sequence: (_a = track === null || track === void 0 ? void 0 : track.sequence) !== null && _a !== void 0 ? _a : null,
144
+ splitFrame,
145
+ propStatuses: sequencePropStatuses,
146
+ });
147
+ if (!eligibility.canSplit) {
148
+ (0, NotificationCenter_1.showNotification)(eligibility.reason, 4000);
149
+ return Promise.resolve(false);
150
+ }
151
+ return splitSequence({
152
+ nodePathInfo: eligibility.nodePathInfo,
153
+ splitFrame,
154
+ });
155
+ };
156
+ exports.splitSelectedTimelineItems = splitSelectedTimelineItems;
@@ -234,6 +234,8 @@ const formatTimelineFieldValueForDisplay = ({ fieldSchema, value, }) => {
234
234
  })) !== null && _d !== void 0 ? _d : formatUnknownTimelineValueForDisplay(value));
235
235
  case 'uv-coordinate':
236
236
  return ((_e = formatUvCoordinateTimelineFieldValueForDisplay({ fieldSchema, value })) !== null && _e !== void 0 ? _e : formatUnknownTimelineValueForDisplay(value));
237
+ case 'text-content':
238
+ return String(value);
237
239
  case 'array':
238
240
  case 'boolean':
239
241
  case 'color':
@@ -44,6 +44,7 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
44
44
  getDragOverrides,
45
45
  getEffectDragOverrides,
46
46
  propStatuses,
47
+ includeTextContent: false,
47
48
  }), [
48
49
  propStatuses,
49
50
  getDragOverrides,
@@ -0,0 +1,30 @@
1
+ import type { TSequence } from 'remotion';
2
+ import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
3
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
4
+ type SequenceNameSaveAction = {
5
+ type: 'noop';
6
+ } | {
7
+ type: 'save';
8
+ defaultValue: string | null;
9
+ };
10
+ export declare const getSequenceNameSaveAction: ({ editedName, currentDisplayName, fallbackDisplayName, hasStaticNameProp, }: {
11
+ editedName: string;
12
+ currentDisplayName: string;
13
+ fallbackDisplayName: string;
14
+ hasStaticNameProp: boolean;
15
+ }) => SequenceNameSaveAction;
16
+ export declare const useRenameSequence: ({ clientId, nodePathInfo, sequence, validatedLocation, }: {
17
+ readonly clientId: string | null;
18
+ readonly nodePathInfo: SequenceNodePathInfo | null;
19
+ readonly sequence: TSequence;
20
+ readonly validatedLocation: CodePosition | null;
21
+ }) => {
22
+ canRename: boolean;
23
+ codeNameStatus: import("remotion").CanUpdateSequencePropStatus | undefined;
24
+ displayName: string;
25
+ fallbackDisplayName: string;
26
+ hasStaticNameProp: boolean;
27
+ propStatusesForOverride: Record<string, import("remotion").CanUpdateSequencePropStatus> | undefined;
28
+ saveName: (name: string) => Promise<void>;
29
+ };
30
+ export {};
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useRenameSequence = exports.getSequenceNameSaveAction = void 0;
4
+ const react_1 = require("react");
5
+ const remotion_1 = require("remotion");
6
+ const save_sequence_prop_1 = require("./save-sequence-prop");
7
+ const getSequenceNameSaveAction = ({ editedName, currentDisplayName, fallbackDisplayName, hasStaticNameProp, }) => {
8
+ if (!hasStaticNameProp &&
9
+ (editedName === '' || editedName === fallbackDisplayName)) {
10
+ return { type: 'noop' };
11
+ }
12
+ if (hasStaticNameProp && editedName === currentDisplayName) {
13
+ return { type: 'noop' };
14
+ }
15
+ return {
16
+ type: 'save',
17
+ defaultValue: editedName === '' ? JSON.stringify('') : null,
18
+ };
19
+ };
20
+ exports.getSequenceNameSaveAction = getSequenceNameSaveAction;
21
+ const useRenameSequence = ({ clientId, nodePathInfo, sequence, validatedLocation, }) => {
22
+ var _a;
23
+ var _b, _c;
24
+ const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
25
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
26
+ const nodePath = (_b = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _b !== void 0 ? _b : null;
27
+ const propStatusesForOverride = (0, react_1.useMemo)(() => {
28
+ return nodePath
29
+ ? remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePath)
30
+ : undefined;
31
+ }, [propStatuses, nodePath]);
32
+ const codeNameStatus = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.name;
33
+ const fallbackDisplayName = (_c = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.componentName) !== null && _c !== void 0 ? _c : '<Sequence>';
34
+ const staticNamePropValue = (codeNameStatus === null || codeNameStatus === void 0 ? void 0 : codeNameStatus.status) === 'static' &&
35
+ typeof codeNameStatus.codeValue === 'string'
36
+ ? codeNameStatus.codeValue
37
+ : null;
38
+ const hasStaticNameProp = staticNamePropValue !== null;
39
+ const displayName = (0, react_1.useMemo)(() => {
40
+ if (staticNamePropValue !== null) {
41
+ return staticNamePropValue;
42
+ }
43
+ if ((codeNameStatus === null || codeNameStatus === void 0 ? void 0 : codeNameStatus.status) === 'static') {
44
+ return fallbackDisplayName;
45
+ }
46
+ return sequence.displayName;
47
+ }, [
48
+ codeNameStatus === null || codeNameStatus === void 0 ? void 0 : codeNameStatus.status,
49
+ fallbackDisplayName,
50
+ sequence.displayName,
51
+ staticNamePropValue,
52
+ ]);
53
+ const canRename = clientId !== null &&
54
+ !window.remotion_isReadOnlyStudio &&
55
+ Boolean(sequence.controls) &&
56
+ nodePath !== null &&
57
+ validatedLocation !== null &&
58
+ codeNameStatus !== undefined &&
59
+ codeNameStatus !== null &&
60
+ codeNameStatus.status === 'static';
61
+ const saveName = (0, react_1.useCallback)(async (name) => {
62
+ if (!canRename ||
63
+ clientId === null ||
64
+ !sequence.controls ||
65
+ !nodePath ||
66
+ !validatedLocation) {
67
+ return;
68
+ }
69
+ const action = (0, exports.getSequenceNameSaveAction)({
70
+ editedName: name,
71
+ currentDisplayName: displayName,
72
+ fallbackDisplayName,
73
+ hasStaticNameProp,
74
+ });
75
+ if (action.type === 'noop') {
76
+ return;
77
+ }
78
+ await (0, save_sequence_prop_1.saveSequenceProps)({
79
+ changes: [
80
+ {
81
+ fileName: validatedLocation.source,
82
+ nodePath,
83
+ fieldKey: 'name',
84
+ value: name,
85
+ defaultValue: action.defaultValue,
86
+ schema: sequence.controls.schema,
87
+ },
88
+ ],
89
+ setPropStatuses,
90
+ clientId,
91
+ undoLabel: 'Rename sequence',
92
+ redoLabel: 'Rename sequence again',
93
+ });
94
+ }, [
95
+ canRename,
96
+ clientId,
97
+ displayName,
98
+ fallbackDisplayName,
99
+ hasStaticNameProp,
100
+ nodePath,
101
+ sequence.controls,
102
+ setPropStatuses,
103
+ validatedLocation,
104
+ ]);
105
+ return {
106
+ canRename,
107
+ codeNameStatus,
108
+ displayName,
109
+ fallbackDisplayName,
110
+ hasStaticNameProp,
111
+ propStatusesForOverride,
112
+ saveName,
113
+ };
114
+ };
115
+ exports.useRenameSequence = useRenameSequence;
@@ -1,8 +1,9 @@
1
1
  import { type TSequence } from 'remotion';
2
2
  import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
- export declare const useTimelineExpandedTree: ({ sequence, nodePathInfo, }: {
3
+ export declare const useTimelineExpandedTree: ({ sequence, nodePathInfo, includeTextContent, }: {
4
4
  readonly sequence: TSequence;
5
5
  readonly nodePathInfo: SequenceNodePathInfo;
6
+ readonly includeTextContent: boolean;
6
7
  }) => {
7
8
  filteredTree: import("../../helpers/timeline-layout").TimelineTreeNode[];
8
9
  getIsExpanded: import("../ExpandedTracksProvider").GetIsExpanded;
@@ -8,7 +8,7 @@ const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
8
8
  const get_node_keyframes_1 = require("./get-node-keyframes");
9
9
  const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
10
10
  const TimelineSelection_1 = require("./TimelineSelection");
11
- const useTimelineExpandedTree = ({ sequence, nodePathInfo, }) => {
11
+ const useTimelineExpandedTree = ({ sequence, nodePathInfo, includeTextContent, }) => {
12
12
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
13
13
  const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
14
14
  const { propStatuses: visualModePropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
@@ -20,12 +20,14 @@ const useTimelineExpandedTree = ({ sequence, nodePathInfo, }) => {
20
20
  getDragOverrides,
21
21
  getEffectDragOverrides,
22
22
  propStatuses: visualModePropStatuses,
23
+ includeTextContent,
23
24
  }), [
24
25
  sequence,
25
26
  nodePathInfo,
26
27
  getDragOverrides,
27
28
  getEffectDragOverrides,
28
29
  visualModePropStatuses,
30
+ includeTextContent,
29
31
  ]);
30
32
  const selectedRowKeys = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.getSelectedTimelineExpandedRowKeys)(selectedItems), [selectedItems]);
31
33
  const filteredTree = (0, react_1.useMemo)(() => (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
@@ -37,6 +37,7 @@ const useTimelineHeight = ({ shown, hasBeenCut, }) => {
37
37
  getDragOverrides,
38
38
  getEffectDragOverrides,
39
39
  propStatuses,
40
+ includeTextContent: false,
40
41
  });
41
42
  const filteredTree = (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
42
43
  nodes: tree,
@@ -108,6 +108,9 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
108
108
  closeMenu();
109
109
  setSelectedModal({
110
110
  type: 'new-comp',
111
+ folderName: null,
112
+ parentName: null,
113
+ stack: null,
111
114
  });
112
115
  },
113
116
  quickSwitcherLabel: 'New composition...',
@@ -76,6 +76,26 @@ const getFolderMenuItems = ({ closeMenu, connectionStatus, folder, readOnlyStudi
76
76
  id: 'show-folder-in-editor-divider',
77
77
  }
78
78
  : null,
79
+ {
80
+ id: 'new-composition-in-folder',
81
+ keyHint: null,
82
+ label: `New composition...`,
83
+ leftItem: null,
84
+ onClick: () => {
85
+ closeMenu();
86
+ setSelectedModal({
87
+ type: 'new-comp',
88
+ folderName: folder.name,
89
+ parentName: folder.parent,
90
+ stack: folder.stack,
91
+ });
92
+ },
93
+ quickSwitcherLabel: 'New composition in folder...',
94
+ subMenu: null,
95
+ type: 'item',
96
+ value: 'new-composition-in-folder',
97
+ disabled: codemodDisabled,
98
+ },
79
99
  {
80
100
  id: 'rename-folder',
81
101
  keyHint: null,
@@ -0,0 +1,4 @@
1
+ export declare const optionsSidebarTabs: import("react").RefObject<{
2
+ selectInspectorPanel: () => void;
3
+ selectRendersPanel: () => void;
4
+ } | null>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.optionsSidebarTabs = void 0;
4
+ const react_1 = require("react");
5
+ exports.optionsSidebarTabs = (0, react_1.createRef)();