@remotion/studio 4.0.483 → 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 (113) hide show
  1. package/dist/components/ColorPicker/ColorPicker.js +65 -3
  2. package/dist/components/ColorPicker/ColorPickerPopup.d.ts +1 -0
  3. package/dist/components/ColorPicker/ColorPickerPopup.js +3 -2
  4. package/dist/components/ContextMenu.js +75 -1
  5. package/dist/components/CurrentComposition.js +3 -2
  6. package/dist/components/InlineCompositionName.d.ts +7 -0
  7. package/dist/components/InlineCompositionName.js +58 -0
  8. package/dist/components/InlineEditableTitle.d.ts +7 -0
  9. package/dist/components/InlineEditableTitle.js +129 -0
  10. package/dist/components/InspectorPanel/EasingInspector.js +184 -10
  11. package/dist/components/InspectorPanel/KeyframeEasingNavigator.d.ts +14 -0
  12. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +146 -0
  13. package/dist/components/InspectorPanel/KeyframeInspector.d.ts +1 -1
  14. package/dist/components/InspectorPanel/KeyframeInspector.js +229 -5
  15. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +17 -0
  16. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +80 -0
  17. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -58
  18. package/dist/components/InspectorPanel/common.d.ts +12 -0
  19. package/dist/components/InspectorPanel/common.js +78 -1
  20. package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +14 -0
  21. package/dist/components/InspectorPanel/easing-inspector-selection.js +18 -0
  22. package/dist/components/InspectorPanel/keyframe-easing-navigator-items.d.ts +24 -0
  23. package/dist/components/InspectorPanel/keyframe-easing-navigator-items.js +40 -0
  24. package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +8 -0
  25. package/dist/components/InspectorPanel/keyframe-inspector-frame.js +14 -0
  26. package/dist/components/InspectorPanel/styles.d.ts +1 -0
  27. package/dist/components/InspectorPanel/styles.js +9 -3
  28. package/dist/components/InspectorSequenceSection.js +37 -10
  29. package/dist/components/Modals.js +1 -1
  30. package/dist/components/NewComposition/CodemodFooter.d.ts +7 -1
  31. package/dist/components/NewComposition/CodemodFooter.js +17 -12
  32. package/dist/components/NewComposition/DeleteComposition.js +7 -1
  33. package/dist/components/NewComposition/DeleteFolder.js +7 -1
  34. package/dist/components/NewComposition/DuplicateComposition.js +17 -10
  35. package/dist/components/NewComposition/InputAndValidationContainer.d.ts +3 -0
  36. package/dist/components/NewComposition/InputAndValidationContainer.js +15 -0
  37. package/dist/components/NewComposition/NewCompDuration.js +7 -6
  38. package/dist/components/NewComposition/NewComposition.d.ts +5 -1
  39. package/dist/components/NewComposition/NewComposition.js +29 -86
  40. package/dist/components/NewComposition/RenameComposition.js +13 -14
  41. package/dist/components/NewComposition/RenameFolder.js +9 -2
  42. package/dist/components/NewComposition/RenameStaticFile.js +2 -1
  43. package/dist/components/NewComposition/ValidationMessage.js +9 -1
  44. package/dist/components/OptionsPanel.d.ts +0 -3
  45. package/dist/components/OptionsPanel.js +7 -3
  46. package/dist/components/Preview.js +1 -1
  47. package/dist/components/RenderModal/ServerRenderModal.js +4 -3
  48. package/dist/components/RenderModal/WebRenderModal.js +2 -1
  49. package/dist/components/SelectedOutlineElement.js +45 -3
  50. package/dist/components/SelectedOutlineOverlay.d.ts +3 -1
  51. package/dist/components/SelectedOutlineOverlay.js +48 -15
  52. package/dist/components/Timeline/EasingEditorModal.js +9 -4
  53. package/dist/components/Timeline/TimelineDeleteKeybindings.js +45 -2
  54. package/dist/components/Timeline/TimelineEffectPropItem.js +82 -1
  55. package/dist/components/Timeline/TimelineExpandedSection.js +1 -0
  56. package/dist/components/Timeline/TimelineInOutPointerHandle.js +2 -1
  57. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -1
  58. package/dist/components/Timeline/TimelineKeyframeControls.js +38 -7
  59. package/dist/components/Timeline/TimelineKeyframeEasingLine.d.ts +4 -0
  60. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +12 -6
  61. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  62. package/dist/components/Timeline/TimelineSelection.js +1 -0
  63. package/dist/components/Timeline/TimelineSequenceItem.js +13 -62
  64. package/dist/components/Timeline/TimelineSequenceName.d.ts +1 -0
  65. package/dist/components/Timeline/TimelineSequenceName.js +7 -6
  66. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +1 -1
  67. package/dist/components/Timeline/TimelineSequencePropItem.js +86 -4
  68. package/dist/components/Timeline/TimelineSlider.js +17 -3
  69. package/dist/components/Timeline/TimelineTextContentField.d.ts +12 -0
  70. package/dist/components/Timeline/TimelineTextContentField.js +100 -0
  71. package/dist/components/Timeline/TimelineWidthProvider.js +18 -3
  72. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +8 -2
  73. package/dist/components/Timeline/delete-selected-timeline-item.js +80 -1
  74. package/dist/components/Timeline/focus-inspector-field.d.ts +16 -0
  75. package/dist/components/Timeline/focus-inspector-field.js +49 -0
  76. package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +18 -0
  77. package/dist/components/Timeline/get-animation-item-selection-for-frame.js +49 -0
  78. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +15 -0
  79. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +26 -0
  80. package/dist/components/Timeline/save-sequence-prop.js +2 -0
  81. package/dist/components/Timeline/split-selected-timeline-item.d.ts +38 -0
  82. package/dist/components/Timeline/split-selected-timeline-item.js +156 -0
  83. package/dist/components/Timeline/timeline-field-display-utils.js +2 -0
  84. package/dist/components/Timeline/update-selected-easing.d.ts +1 -0
  85. package/dist/components/Timeline/update-selected-easing.js +4 -3
  86. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +1 -0
  87. package/dist/components/Timeline/use-rename-sequence.d.ts +30 -0
  88. package/dist/components/Timeline/use-rename-sequence.js +115 -0
  89. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +2 -1
  90. package/dist/components/Timeline/use-timeline-expanded-tree.js +3 -1
  91. package/dist/components/Timeline/use-timeline-height.js +1 -0
  92. package/dist/components/composition-menu-items.js +3 -0
  93. package/dist/components/folder-menu-items.js +20 -0
  94. package/dist/components/options-sidebar-tabs.d.ts +4 -0
  95. package/dist/components/options-sidebar-tabs.js +5 -0
  96. package/dist/components/selected-outline-types.d.ts +6 -1
  97. package/dist/esm/{chunk-fq0j774v.js → chunk-103pp4n7.js} +17652 -15098
  98. package/dist/esm/internals.mjs +17652 -15098
  99. package/dist/esm/previewEntry.mjs +18357 -15803
  100. package/dist/esm/renderEntry.mjs +1 -1
  101. package/dist/helpers/render-codec-label.d.ts +1 -1
  102. package/dist/helpers/timeline-layout.d.ts +4 -3
  103. package/dist/helpers/timeline-layout.js +3 -1
  104. package/dist/helpers/use-create-composition.d.ts +35 -0
  105. package/dist/helpers/use-create-composition.js +111 -0
  106. package/dist/helpers/use-menu-structure.js +0 -14
  107. package/dist/helpers/use-rename-composition.d.ts +16 -0
  108. package/dist/helpers/use-rename-composition.js +49 -0
  109. package/dist/state/modals.d.ts +3 -0
  110. package/dist/state/timeline-zoom.js +17 -14
  111. package/dist/state/z-index.d.ts +1 -0
  112. package/dist/state/z-index.js +11 -2
  113. package/package.json +12 -12
@@ -4,38 +4,212 @@ exports.EasingInspector = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const client_id_1 = require("../../helpers/client-id");
8
+ const timeline_layout_1 = require("../../helpers/timeline-layout");
9
+ const plus_1 = require("../../icons/plus");
10
+ const render_frame_1 = require("../../state/render-frame");
7
11
  const is_menu_item_1 = require("../Menu/is-menu-item");
8
- const SegmentedControl_1 = require("../SegmentedControl");
12
+ const call_add_keyframe_1 = require("../Timeline/call-add-keyframe");
9
13
  const EasingEditorModal_1 = require("../Timeline/EasingEditorModal");
10
14
  const TimelineSelection_1 = require("../Timeline/TimelineSelection");
11
15
  const update_selected_easing_1 = require("../Timeline/update-selected-easing");
12
16
  const common_1 = require("./common");
17
+ const easing_inspector_selection_1 = require("./easing-inspector-selection");
18
+ const KeyframeEasingNavigator_1 = require("./KeyframeEasingNavigator");
19
+ const SequenceInspectorHeader_1 = require("./SequenceInspectorHeader");
13
20
  const styles_1 = require("./styles");
21
+ const use_track_for_selection_1 = require("./use-track-for-selection");
22
+ const addKeyframeIcon = {
23
+ display: 'block',
24
+ height: 13,
25
+ width: 12,
26
+ };
14
27
  const EasingInspector = ({ selection }) => {
28
+ var _a, _b;
29
+ const track = (0, use_track_for_selection_1.useTrackForSelection)(selection);
30
+ const videoConfig = (0, remotion_1.useVideoConfig)();
31
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
15
32
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
16
33
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(remotion_1.Internals.OverrideIdsToNodePathsGettersContext);
17
34
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
18
- const initialEasing = (0, react_1.useMemo)(() => (0, update_selected_easing_1.getTimelineEasingValueForSelection)({
35
+ const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
36
+ const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
37
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
38
+ const { selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
39
+ const parentSelection = (0, react_1.useMemo)(() => (0, TimelineSelection_1.getTimelineSelectionFromNodePathInfo)(selection.nodePathInfo), [selection.nodePathInfo]);
40
+ const easingUpdate = (0, react_1.useMemo)(() => (0, update_selected_easing_1.getSelectedEasingUpdate)({
19
41
  selection,
20
42
  sequences,
21
43
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
22
44
  propStatuses,
23
45
  }), [overrideIdToNodePathMappings, propStatuses, selection, sequences]);
46
+ const initialEasing = (_a = easingUpdate === null || easingUpdate === void 0 ? void 0 : easingUpdate.currentEasing) !== null && _a !== void 0 ? _a : null;
47
+ const easingDetails = (0, react_1.useMemo)(() => {
48
+ var _a, _b, _c, _d, _e, _f, _g;
49
+ if (easingUpdate === null || track === null) {
50
+ return null;
51
+ }
52
+ if (easingUpdate.type === 'sequence') {
53
+ const sequenceDragOverrideValue = ((_a = getDragOverrides(easingUpdate.nodePath)) !== null && _a !== void 0 ? _a : {})[easingUpdate.fieldKey];
54
+ if (!track.sequence.controls) {
55
+ return {
56
+ defaultValue: undefined,
57
+ dragOverrideValue: sequenceDragOverrideValue,
58
+ fieldLabel: easingUpdate.fieldKey,
59
+ };
60
+ }
61
+ const sequenceFields = (0, timeline_layout_1.getFieldsToShow)({
62
+ schema: track.sequence.controls.schema,
63
+ currentRuntimeValueDotNotation: track.sequence.controls.currentRuntimeValueDotNotation,
64
+ getDragOverrides,
65
+ propStatuses,
66
+ nodePath: easingUpdate.nodePath,
67
+ });
68
+ const sequenceField = (_b = sequenceFields === null || sequenceFields === void 0 ? void 0 : sequenceFields.find((candidate) => candidate.key === easingUpdate.fieldKey)) !== null && _b !== void 0 ? _b : null;
69
+ return {
70
+ defaultValue: sequenceField === null || sequenceField === void 0 ? void 0 : sequenceField.fieldSchema.default,
71
+ dragOverrideValue: sequenceDragOverrideValue,
72
+ fieldLabel: (_d = (_c = sequenceField === null || sequenceField === void 0 ? void 0 : sequenceField.description) !== null && _c !== void 0 ? _c : sequenceField === null || sequenceField === void 0 ? void 0 : sequenceField.key) !== null && _d !== void 0 ? _d : easingUpdate.fieldKey,
73
+ };
74
+ }
75
+ const effectDragOverrideValue = getEffectDragOverrides(easingUpdate.nodePath, easingUpdate.effectIndex)[easingUpdate.fieldKey];
76
+ const effect = track.sequence.effects[easingUpdate.effectIndex];
77
+ if (!effect) {
78
+ return {
79
+ defaultValue: undefined,
80
+ dragOverrideValue: effectDragOverrideValue,
81
+ fieldLabel: easingUpdate.fieldKey,
82
+ };
83
+ }
84
+ const effectFields = (0, timeline_layout_1.getEffectFieldsToShow)({
85
+ effect,
86
+ effectIndex: easingUpdate.effectIndex,
87
+ nodePath: easingUpdate.nodePath,
88
+ propStatuses,
89
+ getEffectDragOverrides,
90
+ });
91
+ const effectField = (_e = effectFields.find((candidate) => candidate.key === easingUpdate.fieldKey)) !== null && _e !== void 0 ? _e : null;
92
+ return {
93
+ defaultValue: effectField === null || effectField === void 0 ? void 0 : effectField.fieldSchema.default,
94
+ dragOverrideValue: effectDragOverrideValue,
95
+ fieldLabel: (_g = (_f = effectField === null || effectField === void 0 ? void 0 : effectField.description) !== null && _f !== void 0 ? _f : effectField === null || effectField === void 0 ? void 0 : effectField.key) !== null && _g !== void 0 ? _g : easingUpdate.fieldKey,
96
+ };
97
+ }, [
98
+ easingUpdate,
99
+ getDragOverrides,
100
+ getEffectDragOverrides,
101
+ propStatuses,
102
+ track,
103
+ ]);
104
+ const fieldLabel = (_b = easingDetails === null || easingDetails === void 0 ? void 0 : easingDetails.fieldLabel) !== null && _b !== void 0 ? _b : null;
105
+ const currentEasingSelection = (0, react_1.useMemo)(() => {
106
+ if (easingUpdate === null || track === null) {
107
+ return null;
108
+ }
109
+ return (0, easing_inspector_selection_1.getEasingSelectionFromCurrentKeyframes)({
110
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
111
+ nodePathInfo: selection.nodePathInfo,
112
+ propStatus: easingUpdate.propStatus,
113
+ segmentIndex: easingUpdate.segmentIndex,
114
+ });
115
+ }, [easingUpdate, selection.nodePathInfo, track]);
24
116
  const state = (0, react_1.useMemo)(() => {
25
- if (initialEasing === null) {
117
+ if (initialEasing === null || currentEasingSelection === null) {
26
118
  return null;
27
119
  }
28
120
  return {
29
121
  initialEasing,
30
- selections: [selection],
122
+ selections: [currentEasingSelection],
123
+ };
124
+ }, [currentEasingSelection, initialEasing]);
125
+ const onSelectParent = (0, react_1.useCallback)((event) => {
126
+ event.stopPropagation();
127
+ if (parentSelection === null) {
128
+ return;
129
+ }
130
+ selectItems([parentSelection], { reveal: true });
131
+ }, [parentSelection, selectItems]);
132
+ const canAddKeyframeAtPlayhead = currentEasingSelection !== null &&
133
+ timelinePosition > currentEasingSelection.fromFrame &&
134
+ timelinePosition < currentEasingSelection.toFrame;
135
+ const addKeyframeTime = (0, render_frame_1.renderFrame)(timelinePosition, videoConfig.fps);
136
+ const addKeyframeDisabled = previewServerState.type !== 'connected';
137
+ const onAddKeyframeAtPlayhead = (0, react_1.useCallback)((event) => {
138
+ event.stopPropagation();
139
+ if (!canAddKeyframeAtPlayhead ||
140
+ easingUpdate === null ||
141
+ easingDetails === null ||
142
+ track === null ||
143
+ previewServerState.type !== 'connected') {
144
+ return;
145
+ }
146
+ const sourceFrame = timelinePosition - track.keyframeDisplayOffset;
147
+ const value = remotion_1.Internals.getEffectiveVisualModeValue({
148
+ propStatus: easingUpdate.propStatus,
149
+ dragOverrideValue: easingDetails.dragOverrideValue,
150
+ defaultValue: easingDetails.defaultValue,
151
+ frame: sourceFrame,
152
+ shouldResortToDefaultValueIfUndefined: true,
153
+ });
154
+ const keyframeSelection = {
155
+ type: 'keyframe',
156
+ nodePathInfo: selection.nodePathInfo,
157
+ frame: timelinePosition,
31
158
  };
32
- }, [initialEasing, selection]);
33
- const renderHeader = (0, react_1.useCallback)((modeItems) => (jsx_runtime_1.jsx(common_1.InspectorSectionHeader, { children: jsx_runtime_1.jsx("div", { style: styles_1.sectionHeaderRow, children: jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderStart, children: [
34
- jsx_runtime_1.jsx("span", { style: styles_1.sectionHeaderTitle, children: "Easing" }), jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: modeItems, needsWrapping: false, size: "compact" })
35
- ] }) }) })), []);
36
- if (state === null) {
159
+ if (easingUpdate.type === 'sequence') {
160
+ (0, call_add_keyframe_1.callAddSequenceKeyframe)({
161
+ fileName: easingUpdate.fileName,
162
+ nodePath: easingUpdate.nodePath,
163
+ fieldKey: easingUpdate.fieldKey,
164
+ sourceFrame,
165
+ value,
166
+ schema: easingUpdate.schema,
167
+ setPropStatuses,
168
+ clientId: previewServerState.clientId,
169
+ }).catch(() => undefined);
170
+ }
171
+ else {
172
+ (0, call_add_keyframe_1.callAddEffectKeyframe)({
173
+ fileName: easingUpdate.fileName,
174
+ nodePath: easingUpdate.nodePath,
175
+ effectIndex: easingUpdate.effectIndex,
176
+ fieldKey: easingUpdate.fieldKey,
177
+ sourceFrame,
178
+ value,
179
+ schema: easingUpdate.schema,
180
+ setPropStatuses,
181
+ clientId: previewServerState.clientId,
182
+ }).catch(() => undefined);
183
+ }
184
+ selectItems([keyframeSelection], { reveal: true });
185
+ }, [
186
+ canAddKeyframeAtPlayhead,
187
+ easingDetails,
188
+ easingUpdate,
189
+ previewServerState,
190
+ selectItems,
191
+ selection.nodePathInfo,
192
+ setPropStatuses,
193
+ timelinePosition,
194
+ track,
195
+ ]);
196
+ const renderHeader = (0, react_1.useCallback)(() => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
197
+ jsx_runtime_1.jsx(common_1.InspectorBackHeaderWithDivider, { disabled: parentSelection === null, onClick: onSelectParent, title: "Back to property", children: jsx_runtime_1.jsx("div", { style: styles_1.sectionHeaderTitle, children: fieldLabel }) }), easingUpdate === null || track === null ? null : (jsx_runtime_1.jsx(KeyframeEasingNavigator_1.KeyframeEasingNavigator, { currentSelection: currentEasingSelection !== null && currentEasingSelection !== void 0 ? currentEasingSelection : selection, includeEasings: true, keyframes: easingUpdate.propStatus.keyframes.map((keyframe) => ({
198
+ ...keyframe,
199
+ frame: keyframe.frame + track.keyframeDisplayOffset,
200
+ })), nodePathInfo: selection.nodePathInfo }))] })), [
201
+ currentEasingSelection,
202
+ easingUpdate,
203
+ fieldLabel,
204
+ onSelectParent,
205
+ parentSelection,
206
+ selection,
207
+ track,
208
+ ]);
209
+ if (state === null || track === null || currentEasingSelection === null) {
37
210
  return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Easing unavailable" });
38
211
  }
39
- return (jsx_runtime_1.jsx("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(EasingEditorModal_1.EasingEditor, { state: state, renderHeader: renderHeader }, (0, TimelineSelection_1.getTimelineSelectionKey)(selection)) }));
212
+ return (jsx_runtime_1.jsxs("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: [
213
+ jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeaderWithDivider, { track: track }), jsx_runtime_1.jsx(EasingEditorModal_1.EasingEditor, { state: state, renderHeader: renderHeader }, (0, TimelineSelection_1.getTimelineSelectionKey)(currentEasingSelection)), canAddKeyframeAtPlayhead ? (jsx_runtime_1.jsx("div", { style: styles_1.detailsContainer, children: jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: addKeyframeDisabled, onClick: onAddKeyframeAtPlayhead, renderIcon: (color) => (jsx_runtime_1.jsx(plus_1.Plus, { color: color, style: addKeyframeIcon })), children: `Add keyframe at ${addKeyframeTime}` }) })) : null] }));
40
214
  };
41
215
  exports.EasingInspector = EasingInspector;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
3
+ import { type TimelineSelection } from '../Timeline/TimelineSelection';
4
+ import { type NavigatorKeyframe } from './keyframe-easing-navigator-items';
5
+ export declare const KeyframeEasingNavigator: React.FC<{
6
+ readonly currentSelection: Extract<TimelineSelection, {
7
+ type: 'keyframe';
8
+ } | {
9
+ type: 'easing';
10
+ }>;
11
+ readonly includeEasings: boolean;
12
+ readonly keyframes: readonly NavigatorKeyframe[];
13
+ readonly nodePathInfo: SequenceNodePathInfo;
14
+ }>;
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KeyframeEasingNavigator = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const remotion_1 = require("remotion");
7
+ const colors_1 = require("../../helpers/colors");
8
+ const InlineAction_1 = require("../InlineAction");
9
+ const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
10
+ const TimelineKeyframeDiamondIcon_1 = require("../Timeline/TimelineKeyframeDiamondIcon");
11
+ const TimelineKeyframeEasingLine_1 = require("../Timeline/TimelineKeyframeEasingLine");
12
+ const TimelineSelection_1 = require("../Timeline/TimelineSelection");
13
+ const keyframe_easing_navigator_items_1 = require("./keyframe-easing-navigator-items");
14
+ const navigatorContainer = {
15
+ alignItems: 'center',
16
+ boxSizing: 'border-box',
17
+ display: 'flex',
18
+ gap: 8,
19
+ justifyContent: 'space-between',
20
+ padding: `8px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px 6px`,
21
+ width: '100%',
22
+ };
23
+ const itemStrip = {
24
+ alignItems: 'center',
25
+ display: 'flex',
26
+ flex: 1,
27
+ gap: 0,
28
+ height: 24,
29
+ justifyContent: 'center',
30
+ minWidth: 0,
31
+ };
32
+ const itemButton = {
33
+ alignItems: 'center',
34
+ background: 'none',
35
+ border: 'none',
36
+ display: 'flex',
37
+ height: 24,
38
+ justifyContent: 'center',
39
+ padding: 0,
40
+ };
41
+ const diamondSize = 12;
42
+ const easingLineDiamondOverlap = diamondSize / 2;
43
+ const emptyItem = {
44
+ height: 24,
45
+ width: diamondSize,
46
+ };
47
+ const easingItem = {
48
+ height: 12,
49
+ position: 'relative',
50
+ width: 38,
51
+ };
52
+ const getEasingLineUnderlay = ({ extendLeft, extendRight, }) => {
53
+ return {
54
+ bottom: 0,
55
+ left: extendLeft ? -easingLineDiamondOverlap : 0,
56
+ pointerEvents: 'none',
57
+ position: 'absolute',
58
+ right: extendRight ? -easingLineDiamondOverlap : 0,
59
+ top: 0,
60
+ };
61
+ };
62
+ const chevronIcon = {
63
+ display: 'block',
64
+ height: 12,
65
+ width: 8,
66
+ };
67
+ const disabledChevronColor = 'rgba(255, 255, 255, 0.25)';
68
+ const NavigationChevron = ({ color, direction }) => {
69
+ const path = direction === 'left' ? 'M6 1L2 6L6 11' : 'M2 1L6 6L2 11';
70
+ return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 8 12", style: chevronIcon, children: jsx_runtime_1.jsx("path", { d: path, fill: "none", stroke: color, strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5" }) }));
71
+ };
72
+ const TimelineNavigatorItem = ({ extendLineLeft, extendLineRight, item, onSelect, selected }) => {
73
+ const onClick = (0, react_1.useCallback)(() => {
74
+ if (item === null) {
75
+ return;
76
+ }
77
+ onSelect(item);
78
+ }, [item, onSelect]);
79
+ if (item === null) {
80
+ return jsx_runtime_1.jsx("div", { style: emptyItem });
81
+ }
82
+ const buttonStyle = {
83
+ ...itemButton,
84
+ position: 'relative',
85
+ width: item.type === 'easing' ? 38 : diamondSize,
86
+ zIndex: item.type === 'keyframe' ? 1 : 0,
87
+ };
88
+ const lineUnderlayStyle = getEasingLineUnderlay({
89
+ extendLeft: extendLineLeft,
90
+ extendRight: extendLineRight,
91
+ });
92
+ return (jsx_runtime_1.jsx("button", { type: "button", style: buttonStyle, onClick: onClick, title: item.type === 'keyframe'
93
+ ? `Keyframe at frame ${item.selection.frame}`
94
+ : `Easing from frame ${item.selection.fromFrame} to ${item.selection.toFrame}`, "aria-label": item.type === 'keyframe'
95
+ ? `Select keyframe at frame ${item.selection.frame}`
96
+ : `Select easing from frame ${item.selection.fromFrame} to ${item.selection.toFrame}`, children: item.type === 'keyframe' ? (jsx_runtime_1.jsx(TimelineKeyframeDiamondIcon_1.TimelineKeyframeDiamondIcon, { color: colors_1.LIGHT_TEXT, selected: selected, size: 12 })) : (jsx_runtime_1.jsx("div", { style: easingItem, children: jsx_runtime_1.jsx("div", { style: lineUnderlayStyle, children: jsx_runtime_1.jsx(TimelineKeyframeEasingLine_1.TimelineKeyframeEasingLineVisual, { selected: selected }) }) })) }));
97
+ };
98
+ const KeyframeEasingNavigator = ({ currentSelection, includeEasings, keyframes, nodePathInfo }) => {
99
+ const { isSelected, selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
100
+ const setFrame = remotion_1.Internals.useTimelineSetFrame();
101
+ const videoConfig = (0, remotion_1.useVideoConfig)();
102
+ const items = (0, react_1.useMemo)(() => (0, keyframe_easing_navigator_items_1.getKeyframeEasingNavigatorItems)({
103
+ includeEasings,
104
+ keyframes,
105
+ nodePathInfo,
106
+ }), [includeEasings, keyframes, nodePathInfo]);
107
+ const currentKey = (0, TimelineSelection_1.getTimelineSelectionKey)(currentSelection);
108
+ const currentIndex = items.findIndex((item) => (0, TimelineSelection_1.getTimelineSelectionKey)(item.selection) === currentKey);
109
+ const previousItem = currentIndex > 0 ? items[currentIndex - 1] : null;
110
+ const currentItem = currentIndex === -1 ? null : items[currentIndex];
111
+ const nextItem = currentIndex === -1 || currentIndex >= items.length - 1
112
+ ? null
113
+ : items[currentIndex + 1];
114
+ const selectItem = (0, react_1.useCallback)((item) => {
115
+ selectItems([item.selection], { reveal: true });
116
+ }, [selectItems]);
117
+ const seekToItem = (0, react_1.useCallback)((item) => {
118
+ const frame = (0, keyframe_easing_navigator_items_1.getNavigatorItemPlayheadFrame)(item);
119
+ setFrame((current) => {
120
+ const next = { ...current, [videoConfig.id]: frame };
121
+ remotion_1.Internals.persistCurrentFrame(next);
122
+ return next;
123
+ });
124
+ }, [setFrame, videoConfig.id]);
125
+ const selectPrevious = (0, react_1.useCallback)(() => {
126
+ if (previousItem === null) {
127
+ return;
128
+ }
129
+ seekToItem(previousItem);
130
+ selectItem(previousItem);
131
+ }, [previousItem, seekToItem, selectItem]);
132
+ const selectNext = (0, react_1.useCallback)(() => {
133
+ if (nextItem === null) {
134
+ return;
135
+ }
136
+ seekToItem(nextItem);
137
+ selectItem(nextItem);
138
+ }, [nextItem, seekToItem, selectItem]);
139
+ if (currentItem === null) {
140
+ return null;
141
+ }
142
+ return (jsx_runtime_1.jsxs("div", { style: navigatorContainer, children: [jsx_runtime_1.jsx(InlineAction_1.InlineAction, { disabled: previousItem === null, onClick: selectPrevious, title: "Previous animation item", renderAction: (color) => (jsx_runtime_1.jsx(NavigationChevron, { color: previousItem === null ? disabledChevronColor : color, direction: "left" })) }), jsx_runtime_1.jsxs("div", { style: itemStrip, children: [
143
+ jsx_runtime_1.jsx(TimelineNavigatorItem, { extendLineLeft: false, extendLineRight: currentItem.type === 'keyframe', item: previousItem, onSelect: selectItem, selected: previousItem === null ? false : isSelected(previousItem.selection) }), jsx_runtime_1.jsx(TimelineNavigatorItem, { extendLineLeft: (previousItem === null || previousItem === void 0 ? void 0 : previousItem.type) === 'keyframe', extendLineRight: (nextItem === null || nextItem === void 0 ? void 0 : nextItem.type) === 'keyframe', item: currentItem, onSelect: selectItem, selected: isSelected(currentItem.selection) }), jsx_runtime_1.jsx(TimelineNavigatorItem, { extendLineLeft: currentItem.type === 'keyframe', extendLineRight: false, item: nextItem, onSelect: selectItem, selected: nextItem === null ? false : isSelected(nextItem.selection) })
144
+ ] }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { disabled: nextItem === null, onClick: selectNext, title: "Next animation item", renderAction: (color) => (jsx_runtime_1.jsx(NavigationChevron, { color: nextItem === null ? disabledChevronColor : color, direction: "right" })) })] }));
145
+ };
146
+ exports.KeyframeEasingNavigator = KeyframeEasingNavigator;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { TimelineSelection } from '../Timeline/TimelineSelection';
2
+ import { type TimelineSelection } from '../Timeline/TimelineSelection';
3
3
  export declare const KeyframeInspector: React.FC<{
4
4
  readonly selection: Extract<TimelineSelection, {
5
5
  type: 'keyframe';