@remotion/studio 4.0.506 → 4.0.508

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 (211) hide show
  1. package/dist/FastRefreshProvider.js +13 -9
  2. package/dist/api/copy-render-output-to-asset.d.ts +4 -0
  3. package/dist/api/copy-render-output-to-asset.js +11 -0
  4. package/dist/components/AssetSelector.js +19 -4
  5. package/dist/components/AssetSelectorItem.js +2 -2
  6. package/dist/components/CodingAgentIcon.d.ts +6 -0
  7. package/dist/components/CodingAgentIcon.js +12 -0
  8. package/dist/components/ConfigureDefaultEditorModal.d.ts +1 -3
  9. package/dist/components/ConfigureDefaultEditorModal.js +67 -77
  10. package/dist/components/ConfigureLicenseModal.d.ts +1 -4
  11. package/dist/components/ConfigureLicenseModal.js +89 -81
  12. package/dist/components/ContextMenu.d.ts +1 -0
  13. package/dist/components/ContextMenu.js +42 -13
  14. package/dist/components/EditorContent.js +4 -3
  15. package/dist/components/EditorContexts.js +6 -5
  16. package/dist/components/ExpandedTracksProvider.js +10 -53
  17. package/dist/components/InlineAction.d.ts +2 -1
  18. package/dist/components/InlineAction.js +3 -3
  19. package/dist/components/InspectorLocationCopy.js +8 -8
  20. package/dist/components/InspectorOpenInEditor.d.ts +2 -0
  21. package/dist/components/InspectorOpenInEditor.js +81 -50
  22. package/dist/components/InspectorPanel/AlignmentControls.js +2 -2
  23. package/dist/components/InspectorPanel/CompositionInspector.js +3 -1
  24. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -0
  25. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +22 -4
  26. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -1
  27. package/dist/components/InspectorPanel/styles.js +1 -1
  28. package/dist/components/InspectorSequenceSection.js +36 -4
  29. package/dist/components/Menu/MenuSectionHeader.d.ts +4 -0
  30. package/dist/components/Menu/MenuSectionHeader.js +20 -0
  31. package/dist/components/Menu/SubMenu.js +13 -2
  32. package/dist/components/Menu/menu-tree-context.d.ts +3 -0
  33. package/dist/components/Menu/menu-tree-context.js +13 -0
  34. package/dist/components/MenuBuildIndicator.js +1 -1
  35. package/dist/components/NewComposition/ComboBox.d.ts +6 -1
  36. package/dist/components/NewComposition/MenuContent.js +27 -19
  37. package/dist/components/NewComposition/menu-typeahead.js +2 -2
  38. package/dist/components/PlayPause.d.ts +1 -1
  39. package/dist/components/PlayPause.js +61 -12
  40. package/dist/components/Preview.js +29 -4
  41. package/dist/components/RenderButton.js +16 -12
  42. package/dist/components/RenderModal/GuiRenderStatus.js +23 -6
  43. package/dist/components/RenderModal/InfoBubble.d.ts +1 -0
  44. package/dist/components/RenderModal/InfoBubble.js +6 -4
  45. package/dist/components/RenderModal/InfoTooltip.d.ts +1 -0
  46. package/dist/components/RenderModal/InfoTooltip.js +12 -12
  47. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.d.ts +5 -0
  48. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +16 -3
  49. package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.js +1 -1
  50. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.d.ts +2 -0
  51. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.js +3 -2
  52. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +1 -1
  53. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +1 -1
  54. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +2 -1
  55. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.d.ts +1 -0
  56. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +3 -3
  57. package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.js +1 -1
  58. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +1 -1
  59. package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.js +1 -1
  60. package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.js +1 -1
  61. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +8 -3
  62. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +1 -1
  63. package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.js +1 -1
  64. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +2 -2
  65. package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.js +1 -1
  66. package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.js +1 -1
  67. package/dist/components/RenderModal/SchemaEditor/zod-schema-type.d.ts +1 -0
  68. package/dist/components/RenderModal/SchemaEditor/zod-schema-type.js +12 -1
  69. package/dist/components/RenderModal/ServerRenderModal.js +4 -0
  70. package/dist/components/RenderQueue/RenderQueueItem.js +8 -2
  71. package/dist/components/RenderQueue/actions.d.ts +4 -2
  72. package/dist/components/RenderQueue/actions.js +4 -2
  73. package/dist/components/RenderQueue/index.js +3 -4
  74. package/dist/components/RenderQueue/use-render-output-file-drag.d.ts +8 -0
  75. package/dist/components/RenderQueue/use-render-output-file-drag.js +121 -0
  76. package/dist/components/SegmentedControl.js +0 -1
  77. package/dist/components/SelectedOutlineCanvasRotation.d.ts +9 -0
  78. package/dist/components/SelectedOutlineCanvasRotation.js +237 -0
  79. package/dist/components/SelectedOutlineElement.d.ts +16 -18
  80. package/dist/components/SelectedOutlineElement.js +144 -931
  81. package/dist/components/SelectedOutlineKeyboardControls.d.ts +7 -0
  82. package/dist/components/SelectedOutlineKeyboardControls.js +261 -0
  83. package/dist/components/SelectedOutlineOverlay.d.ts +7 -14
  84. package/dist/components/SelectedOutlineOverlay.js +378 -864
  85. package/dist/components/SelectedOutlinePolygon.d.ts +26 -0
  86. package/dist/components/SelectedOutlinePolygon.js +360 -0
  87. package/dist/components/SelectedOutlineRenderer.d.ts +19 -0
  88. package/dist/components/SelectedOutlineRenderer.js +225 -0
  89. package/dist/components/SelectedOutlineRotationCornerHandle.d.ts +17 -0
  90. package/dist/components/SelectedOutlineRotationCornerHandle.js +271 -0
  91. package/dist/components/SelectedOutlineScaleEdgeLine.d.ts +17 -0
  92. package/dist/components/SelectedOutlineScaleEdgeLine.js +215 -0
  93. package/dist/components/SelectedOutlineSnapIndicators.d.ts +9 -0
  94. package/dist/components/SelectedOutlineSnapIndicators.js +29 -0
  95. package/dist/components/SelectedOutlineTransformOriginHandle.d.ts +9 -0
  96. package/dist/components/SelectedOutlineTransformOriginHandle.js +312 -0
  97. package/dist/components/SelectedOutlineUvControls.d.ts +3 -9
  98. package/dist/components/SelectedOutlineUvControls.js +57 -12
  99. package/dist/components/SequencePropsSubscriptionProvider.js +8 -0
  100. package/dist/components/SettingsContext.d.ts +15 -0
  101. package/dist/components/SettingsContext.js +116 -0
  102. package/dist/components/SettingsModal.js +10 -4
  103. package/dist/components/SettingsModalFooter.d.ts +1 -3
  104. package/dist/components/SettingsModalFooter.js +4 -6
  105. package/dist/components/ShowOutlinesProvider.js +2 -3
  106. package/dist/components/Timeline/EasingEditorModal.js +66 -22
  107. package/dist/components/Timeline/SequencePropsObserver.js +97 -1
  108. package/dist/components/Timeline/SubscribeToNodePaths.js +4 -2
  109. package/dist/components/Timeline/Timeline.js +22 -5
  110. package/dist/components/Timeline/TimelineDuplicateCount.d.ts +4 -0
  111. package/dist/components/Timeline/TimelineDuplicateCount.js +28 -0
  112. package/dist/components/Timeline/TimelineEffectItem.js +1 -4
  113. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +3 -23
  114. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +4 -2
  115. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +11 -1
  116. package/dist/components/Timeline/TimelineFieldRowContent.js +10 -3
  117. package/dist/components/Timeline/TimelineRotationField.js +84 -12
  118. package/dist/components/Timeline/TimelineScaleField.js +58 -4
  119. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  120. package/dist/components/Timeline/TimelineSelection.js +45 -2
  121. package/dist/components/Timeline/TimelineSequence.js +28 -25
  122. package/dist/components/Timeline/TimelineSequenceItem.js +91 -28
  123. package/dist/components/Timeline/TimelineSequencePropItem.js +5 -2
  124. package/dist/components/Timeline/TimelineTrack.js +2 -1
  125. package/dist/components/Timeline/TimelineTransformOriginField.js +78 -4
  126. package/dist/components/Timeline/TimelineTranslateField.js +55 -15
  127. package/dist/components/Timeline/Transform3DModeContext.d.ts +1 -0
  128. package/dist/components/Timeline/Transform3DModeContext.js +5 -0
  129. package/dist/components/Timeline/delete-selected-timeline-item.js +0 -6
  130. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +6 -3
  131. package/dist/components/Timeline/get-sequence-context-menu-items.js +69 -57
  132. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
  133. package/dist/components/Timeline/sequence-props-subscription-store.js +5 -2
  134. package/dist/components/Timeline/timeline-field-display-utils.js +2 -2
  135. package/dist/components/Timeline/timeline-field-row-layout.d.ts +6 -0
  136. package/dist/components/Timeline/timeline-field-row-layout.js +16 -1
  137. package/dist/components/Timeline/timeline-rotation-utils.d.ts +16 -0
  138. package/dist/components/Timeline/timeline-rotation-utils.js +145 -4
  139. package/dist/components/Timeline/timeline-translate-utils.d.ts +3 -2
  140. package/dist/components/Timeline/timeline-translate-utils.js +8 -4
  141. package/dist/components/Timeline/transform-3d-mode.d.ts +6 -0
  142. package/dist/components/Timeline/transform-3d-mode.js +36 -0
  143. package/dist/components/Timeline/transform-origin-utils.d.ts +4 -0
  144. package/dist/components/Timeline/transform-origin-utils.js +12 -6
  145. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +36 -4
  146. package/dist/components/Timeline/{use-open-sequence-in-editor.d.ts → use-open-sequence-in-apps.d.ts} +4 -1
  147. package/dist/components/Timeline/{use-open-sequence-in-editor.js → use-open-sequence-in-apps.js} +21 -5
  148. package/dist/components/Timeline/use-resolved-stack-react-to-change.d.ts +5 -1
  149. package/dist/components/Timeline/use-resolved-stack-react-to-change.js +45 -9
  150. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -1
  151. package/dist/components/Timeline/use-sequence-props-subscription.js +7 -2
  152. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +4 -0
  153. package/dist/components/Timeline/use-timeline-expanded-tree.js +45 -1
  154. package/dist/components/call-api.js +2 -0
  155. package/dist/components/canvas-rotation-cursor.d.ts +1 -0
  156. package/dist/components/canvas-rotation-cursor.js +14 -0
  157. package/dist/components/get-open-in-menu-items.d.ts +17 -0
  158. package/dist/components/get-open-in-menu-items.js +144 -0
  159. package/dist/components/selected-outline-drag.d.ts +11 -5
  160. package/dist/components/selected-outline-drag.js +80 -42
  161. package/dist/components/selected-outline-measurement.d.ts +7 -2
  162. package/dist/components/selected-outline-measurement.js +28 -1
  163. package/dist/components/selected-outline-order.d.ts +12 -0
  164. package/dist/components/selected-outline-order.js +251 -0
  165. package/dist/components/selected-outline-types.d.ts +15 -10
  166. package/dist/components/svg-point-to-client-point.d.ts +2 -0
  167. package/dist/components/svg-point-to-client-point.js +10 -0
  168. package/dist/components/use-auto-save-config.d.ts +8 -0
  169. package/dist/components/use-auto-save-config.js +74 -0
  170. package/dist/components/use-default-editor-info.d.ts +1 -0
  171. package/dist/components/use-default-editor-info.js +10 -30
  172. package/dist/esm/{chunk-jefhcs5z.js → chunk-fgedsvhb.js} +1 -2
  173. package/dist/esm/{chunk-b49ec3nz.js → chunk-zpn4m49r.js} +12924 -10139
  174. package/dist/esm/index.mjs +357 -2
  175. package/dist/esm/internals.mjs +12923 -10138
  176. package/dist/esm/previewEntry.mjs +12771 -9986
  177. package/dist/esm/renderEntry.mjs +2 -2
  178. package/dist/helpers/are-sequence-node-path-infos-equal.d.ts +2 -0
  179. package/dist/helpers/are-sequence-node-path-infos-equal.js +27 -0
  180. package/dist/helpers/calculate-timeline.js +3 -3
  181. package/dist/helpers/client-id.js +8 -1
  182. package/dist/helpers/format-file-location.d.ts +1 -1
  183. package/dist/helpers/format-file-location.js +3 -3
  184. package/dist/helpers/get-box-quads-polyfill-internals.js +10 -2
  185. package/dist/helpers/migrate-expanded-tracks-for-subscription-key.js +3 -3
  186. package/dist/helpers/open-in-editor.d.ts +4 -1
  187. package/dist/helpers/open-in-editor.js +9 -1
  188. package/dist/helpers/preview-server-events.js +4 -0
  189. package/dist/helpers/sequence-node-path-mutations.d.ts +4 -0
  190. package/dist/helpers/sequence-node-path-mutations.js +31 -0
  191. package/dist/helpers/studio-runtime-config.js +3 -0
  192. package/dist/helpers/timeline-node-path-key.d.ts +2 -0
  193. package/dist/helpers/timeline-node-path-key.js +3 -1
  194. package/dist/helpers/use-asset-drag-events.d.ts +2 -1
  195. package/dist/helpers/use-asset-drag-events.js +14 -6
  196. package/dist/helpers/use-menu-structure.js +2 -2
  197. package/dist/helpers/use-runtime-values.d.ts +1 -3
  198. package/dist/icons/cube.d.ts +4 -0
  199. package/dist/icons/cube.js +6 -0
  200. package/dist/icons/finder.d.ts +4 -0
  201. package/dist/icons/finder.js +8 -0
  202. package/dist/icons/terminal.d.ts +6 -0
  203. package/dist/icons/terminal.js +46 -0
  204. package/dist/index.d.ts +15 -0
  205. package/dist/index.js +8 -0
  206. package/dist/state/timeline-sequence-hover.d.ts +9 -3
  207. package/dist/state/timeline-sequence-hover.js +63 -12
  208. package/dist/state/transform-3d-mode.d.ts +10 -0
  209. package/dist/state/transform-3d-mode.js +27 -0
  210. package/dist/state/z-index.js +5 -8
  211. package/package.json +12 -12
@@ -37,9 +37,9 @@ exports.TimelineSequenceItem = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const remotion_1 = require("remotion");
40
+ const are_sequence_node_path_infos_equal_1 = require("../../helpers/are-sequence-node-path-infos-equal");
40
41
  const client_id_1 = require("../../helpers/client-id");
41
42
  const colors_1 = require("../../helpers/colors");
42
- const format_file_location_1 = require("../../helpers/format-file-location");
43
43
  const get_sequence_double_click_action_1 = require("../../helpers/get-sequence-double-click-action");
44
44
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
45
45
  const studio_runtime_config_1 = require("../../helpers/studio-runtime-config");
@@ -48,6 +48,7 @@ const use_keybinding_1 = require("../../helpers/use-keybinding");
48
48
  const use_runtime_values_1 = require("../../helpers/use-runtime-values");
49
49
  const modals_1 = require("../../state/modals");
50
50
  const timeline_sequence_hover_1 = require("../../state/timeline-sequence-hover");
51
+ const transform_3d_mode_1 = require("../../state/transform-3d-mode");
51
52
  const call_api_1 = require("../call-api");
52
53
  const CompositionOrStillIcon_1 = require("../CompositionOrStillIcon");
53
54
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
@@ -65,6 +66,7 @@ const get_sequence_context_menu_items_1 = require("./get-sequence-context-menu-i
65
66
  const imperative_state_1 = require("./imperative-state");
66
67
  const save_sequence_prop_1 = require("./save-sequence-prop");
67
68
  const timeline_asset_link_1 = require("./timeline-asset-link");
69
+ const TimelineDuplicateCount_1 = require("./TimelineDuplicateCount");
68
70
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
69
71
  const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
70
72
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
@@ -72,7 +74,7 @@ const TimelineMediaInfo_1 = require("./TimelineMediaInfo");
72
74
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
73
75
  const TimelineSelection_1 = require("./TimelineSelection");
74
76
  const TimelineSequenceName_1 = require("./TimelineSequenceName");
75
- const use_open_sequence_in_editor_1 = require("./use-open-sequence-in-editor");
77
+ const use_open_sequence_in_apps_1 = require("./use-open-sequence-in-apps");
76
78
  const use_rename_sequence_1 = require("./use-rename-sequence");
77
79
  const use_sequence_freeze_frame_menu_item_1 = require("./use-sequence-freeze-frame-menu-item");
78
80
  const use_timeline_expanded_tree_1 = require("./use-timeline-expanded-tree");
@@ -95,18 +97,29 @@ const effectDropHighlight = {
95
97
  };
96
98
  const SEQUENCE_REORDER_MIME_TYPE = 'application/remotion-sequence-reorder';
97
99
  let currentSequenceDrag = null;
98
- const TimelineSequenceExpandArrow = ({ disabled, isExpanded, nodePathInfo, onToggleExpand, sequence }) => {
99
- const { filteredTree } = (0, use_timeline_expanded_tree_1.useTimelineExpandedTree)({
100
+ const TimelineSequenceExpandArrowInner = ({ disabled, isExpanded, nodePathInfo, sequence }) => {
101
+ const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
102
+ const hasExpandableContent = (0, use_timeline_expanded_tree_1.useTimelineSequenceHasExpandableContent)({
100
103
  sequence,
101
104
  nodePathInfo,
102
- includeTextContent: false,
103
- includeSourceControls: false,
104
105
  });
105
- if (filteredTree.length === 0) {
106
+ const onToggleExpand = (0, react_1.useCallback)(() => toggleTrack(nodePathInfo), [nodePathInfo, toggleTrack]);
107
+ if (!hasExpandableContent) {
106
108
  return jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {});
107
109
  }
108
110
  return (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: onToggleExpand, label: "track properties", disabled: disabled }));
109
111
  };
112
+ const areTimelineSequenceExpandArrowPropsEqual = (first, second) => {
113
+ var _a, _b, _c, _d;
114
+ return (first.disabled === second.disabled &&
115
+ first.isExpanded === second.isExpanded &&
116
+ ((_a = first.sequence.controls) === null || _a === void 0 ? void 0 : _a.schema) === ((_b = second.sequence.controls) === null || _b === void 0 ? void 0 : _b.schema) &&
117
+ ((_c = first.sequence.controls) === null || _c === void 0 ? void 0 : _c.runtimeValues) ===
118
+ ((_d = second.sequence.controls) === null || _d === void 0 ? void 0 : _d.runtimeValues) &&
119
+ first.sequence.effects === second.sequence.effects &&
120
+ (0, are_sequence_node_path_infos_equal_1.areSequenceNodePathInfosEqual)(first.nodePathInfo, second.nodePathInfo));
121
+ };
122
+ const TimelineSequenceExpandArrow = react_1.default.memo(TimelineSequenceExpandArrowInner, areTimelineSequenceExpandArrowPropsEqual);
110
123
  const sequenceReorderWrapper = {
111
124
  position: 'relative',
112
125
  };
@@ -177,14 +190,13 @@ const getDestinationIndex = ({ fromIndex, insertionIndex, }) => {
177
190
  };
178
191
  const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDepth, sequence, nodePathInfo, keyframeDisplayOffset, sequenceFrameOffset, siblingIndex, }) => {
179
192
  var _a, _b;
180
- var _c, _d;
193
+ var _c, _d, _e, _f;
181
194
  const nodePath = (_c = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.sequenceSubscriptionKey) !== null && _c !== void 0 ? _c : null;
182
195
  const { hovered, onPointerEnter, onPointerLeave } = (0, timeline_sequence_hover_1.useTimelineSequenceHover)(nodePathInfo);
183
196
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
184
197
  const previewConnected = previewServerState.type === 'connected';
185
198
  const previewInteractive = previewConnected && (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
186
199
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
187
- const { toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
188
200
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
189
201
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
190
202
  const { isHighestContext } = (0, use_keybinding_1.useKeybinding)();
@@ -197,11 +209,7 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
197
209
  const [isRenaming, setIsRenaming] = (0, react_1.useState)(false);
198
210
  const [sequenceDropIndicator, setSequenceDropIndicator] = (0, react_1.useState)(null);
199
211
  const [sequenceDropRejection, setSequenceDropRejection] = (0, react_1.useState)(null);
200
- const { canOpenInEditor, editorInfo, openInEditor, originalLocation } = (0, use_open_sequence_in_editor_1.useOpenSequenceInEditor)(sequence);
201
- const fileLocation = (0, react_1.useMemo)(() => (0, format_file_location_1.formatFileLocation)({
202
- location: originalLocation,
203
- root: window.remotion_cwd,
204
- }), [originalLocation]);
212
+ const { canOpenInEditor, canConfigureApps, codingAgentInfo, editorInfo, openInCodingAgent, openInEditor, originalLocation, } = (0, use_open_sequence_in_apps_1.useOpenSequenceInApps)(sequence);
205
213
  const validatedLocation = (0, react_1.useMemo)(() => {
206
214
  var _a;
207
215
  if (!originalLocation ||
@@ -226,16 +234,18 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
226
234
  const timelineDisplayName = sequence.displayName === '' && connectedCompositions.length === 1
227
235
  ? connectedCompositions[0].id
228
236
  : displayName;
237
+ const numberOfHiddenDuplicates = Math.max(0, ((_d = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== null && _d !== void 0 ? _d : 1) - 1);
229
238
  const canDeleteFromSource = Boolean(nodePath && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source));
230
239
  const nodePathKey = (0, react_1.useMemo)(() => nodePath ? remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath) : null, [nodePath]);
231
- const parentId = (_d = sequence.parent) !== null && _d !== void 0 ? _d : null;
240
+ const parentId = (_e = sequence.parent) !== null && _e !== void 0 ? _e : null;
232
241
  const canReorderSequence = previewInteractive &&
233
242
  Boolean(nodePath && nodePathKey && (validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source)) &&
234
243
  (nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) === 1;
235
244
  const canHandleSequenceDrag = previewInteractive;
236
245
  const confirm = (0, ConfirmationDialog_1.useConfirmationDialog)();
237
246
  const deleteDisabled = (0, react_1.useMemo)(() => !previewInteractive || !sequence.controls || !canDeleteFromSource, [previewInteractive, sequence.controls, canDeleteFromSource]);
238
- const duplicateDisabled = deleteDisabled;
247
+ const isProgrammaticallyDuplicated = ((_f = nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.numberOfSequencesWithThisNodePath) !== null && _f !== void 0 ? _f : 1) > 1;
248
+ const duplicateDisabled = deleteDisabled || isProgrammaticallyDuplicated;
239
249
  const disableInteractivityDisabled = !previewInteractive ||
240
250
  !sequence.showInTimeline ||
241
251
  !nodePath ||
@@ -471,12 +481,6 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
471
481
  ? sequence.src
472
482
  : null;
473
483
  const isExpanded = previewConnected && nodePathInfo !== null && getIsExpanded(nodePathInfo);
474
- const onToggleExpand = (0, react_1.useCallback)(() => {
475
- if (nodePathInfo === null) {
476
- return;
477
- }
478
- toggleTrack(nodePathInfo);
479
- }, [nodePathInfo, toggleTrack]);
480
484
  const codeHiddenStatus = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride.hidden;
481
485
  const runtimeHidden = (0, use_runtime_values_1.useRuntimeValue)(sequence.controls, 'hidden');
482
486
  const isItemHidden = (0, react_1.useMemo)(() => {
@@ -655,6 +659,8 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
655
659
  });
656
660
  },
657
661
  });
662
+ const canRotate = nodePathInfo !== null;
663
+ const { setManuallyEnabled } = (0, react_1.useContext)(transform_3d_mode_1.Transform3DModeStateContext);
658
664
  const onAddEffect = (0, react_1.useCallback)(() => {
659
665
  if (!canAddEffect ||
660
666
  previewServerState.type !== 'connected' ||
@@ -688,6 +694,20 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
688
694
  key: selected_outline_types_1.cropFieldKeys.left,
689
695
  }, undefined, undefined, { reveal: true });
690
696
  }, [canCrop, nodePathInfo, selectItem]);
697
+ const onRotate = (0, react_1.useCallback)(() => {
698
+ if (!canRotate || !nodePathInfo) {
699
+ return;
700
+ }
701
+ setManuallyEnabled((0, TimelineSelection_1.getTimelineSequenceSelectionKey)(nodePathInfo), true);
702
+ selectItem({
703
+ type: 'sequence-prop',
704
+ nodePathInfo: {
705
+ ...nodePathInfo,
706
+ auxiliaryKeys: ['controls', selected_outline_types_1.rotateFieldKey],
707
+ },
708
+ key: selected_outline_types_1.rotateFieldKey,
709
+ }, undefined, undefined, { reveal: true });
710
+ }, [canRotate, nodePathInfo, selectItem, setManuallyEnabled]);
691
711
  const getContextMenuItems = (0, react_1.useCallback)(() => {
692
712
  var _a;
693
713
  if (selectable) {
@@ -708,15 +728,28 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
708
728
  return (0, get_sequence_context_menu_items_1.getSequenceContextMenuItems)({
709
729
  assetLinkInfo: mediaSrc ? (0, timeline_asset_link_1.getTimelineAssetLinkInfo)(mediaSrc) : null,
710
730
  canOpenInEditor,
731
+ codingAgentInfo,
711
732
  deleteDisabled,
712
733
  disableInteractivityDisabled,
713
734
  duplicateDisabled,
714
735
  editorInfo,
715
- fileLocation,
716
736
  includeSourceEditItems: (0, interactivity_enabled_1.isStudioInteractivityEnabled)(),
737
+ isProgrammaticallyDuplicated,
738
+ onConfigureApps: canConfigureApps
739
+ ? () => {
740
+ var _a;
741
+ var _b;
742
+ setSelectedModal({
743
+ type: 'settings',
744
+ initialTab: 'apps',
745
+ initialPublicLicenseKey: (_b = (_a = window.remotion_renderDefaults) === null || _a === void 0 ? void 0 : _a.publicLicenseKey) !== null && _b !== void 0 ? _b : null,
746
+ });
747
+ }
748
+ : null,
717
749
  onDeleteSequenceFromSource,
718
750
  onDisableSequenceInteractivity,
719
751
  onDuplicateSequenceFromSource,
752
+ openInCodingAgent,
720
753
  openInEditor,
721
754
  originalLocation,
722
755
  selectAsset,
@@ -745,7 +778,7 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
745
778
  type: 'item',
746
779
  id: 'crop',
747
780
  keyHint: null,
748
- label: 'Crop',
781
+ label: isProgrammaticallyDuplicated ? 'Crop all' : 'Crop',
749
782
  leftItem: null,
750
783
  disabled: false,
751
784
  onClick: onCrop,
@@ -753,9 +786,31 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
753
786
  subMenu: null,
754
787
  value: 'crop',
755
788
  },
789
+ ]
790
+ : []),
791
+ ...(canRotate
792
+ ? [
793
+ {
794
+ type: 'item',
795
+ id: 'rotate',
796
+ keyHint: null,
797
+ label: isProgrammaticallyDuplicated
798
+ ? 'Rotate all'
799
+ : 'Rotate',
800
+ leftItem: null,
801
+ disabled: false,
802
+ onClick: onRotate,
803
+ quickSwitcherLabel: null,
804
+ subMenu: null,
805
+ value: 'rotate',
806
+ },
807
+ ]
808
+ : []),
809
+ ...(canCrop || canRotate
810
+ ? [
756
811
  {
757
812
  type: 'divider',
758
- id: 'crop-divider',
813
+ id: 'transform-controls-divider',
759
814
  },
760
815
  ]
761
816
  : []),
@@ -780,23 +835,28 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
780
835
  }, [
781
836
  canAddEffect,
782
837
  canCrop,
838
+ canRotate,
839
+ canConfigureApps,
783
840
  canOpenInEditor,
784
841
  canRenameThisSequence,
842
+ codingAgentInfo,
785
843
  deleteDisabled,
786
844
  disableInteractivityDisabled,
787
845
  duplicateDisabled,
788
846
  editorInfo,
789
- fileLocation,
847
+ isProgrammaticallyDuplicated,
790
848
  mediaSrc,
791
849
  nodePath,
792
850
  nodePathInfo === null || nodePathInfo === void 0 ? void 0 : nodePathInfo.supportsEffects,
793
851
  onAddEffect,
794
852
  onCrop,
853
+ onRotate,
795
854
  onDeleteSequenceFromSource,
796
855
  onDisableSequenceInteractivity,
797
856
  onDuplicateSequenceFromSource,
798
857
  onRenameSequence,
799
858
  onSelect,
859
+ openInCodingAgent,
800
860
  openInEditor,
801
861
  originalLocation,
802
862
  previewInteractive,
@@ -806,6 +866,7 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
806
866
  selectable,
807
867
  sequence,
808
868
  sequenceFrameOffset,
869
+ setSelectedModal,
809
870
  setPropStatuses,
810
871
  validatedLocation === null || validatedLocation === void 0 ? void 0 : validatedLocation.source,
811
872
  ]);
@@ -867,9 +928,11 @@ const TimelineSequenceItemInner = ({ children, connectedCompositions, nestedDept
867
928
  clientId: previewServerState.clientId,
868
929
  });
869
930
  }, [canDropEffect, nodePath, previewServerState, validatedLocation]);
870
- const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, onToggleExpand: onToggleExpand, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, hovered: hovered, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
931
+ const trackRow = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: nestedDepth, eye: canToggleVisibility ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: hasExpandableContent && nodePathInfo !== null ? (jsx_runtime_1.jsx(TimelineSequenceExpandArrow, { disabled: !previewInteractive, isExpanded: isExpanded, nodePathInfo: nodePathInfo, sequence: sequence })) : (jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {})), style: rowStyle, selected: selected, selectable: selectable, selectionItem: selectionItem, onSelect: onSelect, showSelectedBackground: true, containsSelection: containsSelection, hovered: hovered, outerHeight: outerHeight, onDragLeave: canDropEffect ? onEffectDragLeave : undefined, onDragOver: canDropEffect ? onEffectDragOver : undefined, onDrop: canDropEffect ? onEffectDrop : undefined, onDoubleClick: canHandleSequenceDoubleClick ? onSequenceDoubleClick : undefined, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsxs("div", { style: labelContainerStyle, children: [connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
871
932
  jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { color: (0, TimelineSelection_1.getTimelineColor)(false, false), composition: connectedCompositions[0], style: connectedCompositionIconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
872
- ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
933
+ ] })) : null, jsx_runtime_1.jsx(TimelineSequenceName_1.TimelineSequenceName, { displayName: timelineDisplayName, fallbackDisplayName: fallbackDisplayName, selected: selected, containsSelection: containsSelection, editing: isRenaming, onCancelEditing: onCancelRenaming, onSaveName: onSaveName }), numberOfHiddenDuplicates > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
934
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineDuplicateCount_1.TimelineDuplicateCount, { count: numberOfHiddenDuplicates })
935
+ ] })) : null, mediaSrc ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
873
936
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
874
937
  " ",
875
938
  jsx_runtime_1.jsx(TimelineMediaInfo_1.TimelineMediaInfo, { src: mediaSrc })
@@ -45,6 +45,7 @@ const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
45
45
  const call_add_keyframe_1 = require("./call-add-keyframe");
46
46
  const get_sequence_prop_reset_changes_1 = require("./get-sequence-prop-reset-changes");
47
47
  const save_sequence_prop_1 = require("./save-sequence-prop");
48
+ const timeline_field_row_layout_1 = require("./timeline-field-row-layout");
48
49
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
49
50
  const TimelineFieldRowContent_1 = require("./TimelineFieldRowContent");
50
51
  const TimelineKeyframeControls_1 = require("./TimelineKeyframeControls");
@@ -53,6 +54,7 @@ const TimelineLayerEye_1 = require("./TimelineLayerEye");
53
54
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
54
55
  const TimelineSchemaField_1 = require("./TimelineSchemaField");
55
56
  const TimelineSelection_1 = require("./TimelineSelection");
57
+ const Transform3DModeContext_1 = require("./Transform3DModeContext");
56
58
  const fieldRowBase = {};
57
59
  const inlineSourceFieldRow = {
58
60
  alignItems: 'stretch',
@@ -229,6 +231,7 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
229
231
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
230
232
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
231
233
  const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
234
+ const transform3DMode = (0, react_1.useContext)(Transform3DModeContext_1.Transform3DModeContext);
232
235
  const propStatusesForOverride = remotion_1.Internals.getPropStatusesCtx(visualModePropStatuses, nodePath);
233
236
  const propStatus = (_a = propStatusesForOverride === null || propStatusesForOverride === void 0 ? void 0 : propStatusesForOverride[field.key]) !== null && _a !== void 0 ? _a : null;
234
237
  const dragOverrideValue = (0, react_1.useMemo)(() => {
@@ -248,10 +251,10 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
248
251
  keyframable,
249
252
  })) ? (jsx_runtime_1.jsx(TimelineKeyframeControls_1.TimelineKeyframeControls, { fieldKey: field.key, propStatus: propStatus, nodePath: nodePath, fileName: validatedLocation.source, keyframeDisplayOffset: keyframeDisplayOffset, defaultValue: field.fieldSchema.default, dragOverrideValue: dragOverrideValue, schema: schema, effectIndex: null, nodePathInfo: nodePathInfo, mode: keyframeControlsMode })) : null;
250
253
  const style = (0, react_1.useMemo)(() => {
251
- return field.typeName === 'text-content'
254
+ return (0, timeline_field_row_layout_1.isTimelineFieldStacked)({ field, transform3DMode })
252
255
  ? fieldRowBase
253
256
  : { ...fieldRowBase, height: field.rowHeight };
254
- }, [field.rowHeight, field.typeName]);
257
+ }, [field, transform3DMode]);
255
258
  const canResetToDefault = (0, react_1.useMemo)(() => {
256
259
  if (!propStatus || propStatus.status === 'computed') {
257
260
  return false;
@@ -44,6 +44,7 @@ const TimelineExpandedTrackKeyframes_1 = require("./TimelineExpandedTrackKeyfram
44
44
  const TimelineSelection_1 = require("./TimelineSelection");
45
45
  const TimelineSequence_1 = require("./TimelineSequence");
46
46
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
47
+ const emptyConnectedCompositions = [];
47
48
  const TimelineTrackUnmemoized = ({ track }) => {
48
49
  var _a;
49
50
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
@@ -61,7 +62,7 @@ const TimelineTrackUnmemoized = ({ track }) => {
61
62
  previewServerConnected &&
62
63
  getIsExpanded(track.nodePathInfo);
63
64
  return (jsx_runtime_1.jsxs("div", { onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: [
64
- jsx_runtime_1.jsxs("div", { style: layerStyle, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nodePathInfo: track.nodePathInfo, sequenceFrameOffset: track.sequenceFrameOffset })
65
+ jsx_runtime_1.jsxs("div", { style: layerStyle, children: [rowHighlightBackground && timelineWidth !== null ? (jsx_runtime_1.jsx("div", { style: (0, TimelineSelection_1.getTimelineSelectedTrackHighlightStyle)(timelineWidth, rowHighlightBackground) })) : null, jsx_runtime_1.jsx(TimelineSequence_1.TimelineSequence, { s: track.sequence, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : emptyConnectedCompositions, nodePathInfo: track.nodePathInfo, sequenceFrameOffset: track.sequenceFrameOffset })
65
66
  ] }), showExpandedKeyframes && track.nodePathInfo ? (jsx_runtime_1.jsx(TimelineExpandedTrackKeyframes_1.TimelineExpandedTrackKeyframes, { sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset })) : null] }));
66
67
  };
67
68
  exports.TimelineTrack = react_1.default.memo(TimelineTrackUnmemoized);
@@ -8,21 +8,33 @@ const timeline_field_display_utils_1 = require("./timeline-field-display-utils")
8
8
  const timeline_field_utils_1 = require("./timeline-field-utils");
9
9
  const TimelineSchemaField_1 = require("./TimelineSchemaField");
10
10
  const transform_origin_utils_1 = require("./transform-origin-utils");
11
+ const Transform3DModeContext_1 = require("./Transform3DModeContext");
11
12
  const leftDraggerStyle = {
13
+ paddingBottom: 2,
12
14
  paddingLeft: 0,
15
+ paddingTop: 2,
13
16
  };
14
17
  const rightDraggerStyle = {
18
+ paddingBottom: 2,
15
19
  paddingRight: 0,
20
+ paddingTop: 2,
16
21
  };
17
22
  const containerStyle = {
18
23
  display: 'flex',
19
24
  gap: 4,
20
25
  };
21
26
  const TimelineTransformOriginField = ({ field, propStatus, effectiveValue, onSave, onDragValueChange, onDragEnd, }) => {
27
+ var _a;
22
28
  const [dragX, setDragX] = (0, react_1.useState)(null);
23
29
  const [dragY, setDragY] = (0, react_1.useState)(null);
30
+ const [dragZ, setDragZ] = (0, react_1.useState)(null);
31
+ const transform3DMode = (0, react_1.useContext)(Transform3DModeContext_1.Transform3DModeContext);
24
32
  const parsed = (0, react_1.useMemo)(() => (0, transform_origin_utils_1.parseTransformOrigin)(effectiveValue), [effectiveValue]);
25
33
  const percent = (0, react_1.useMemo)(() => (parsed === null ? null : (0, transform_origin_utils_1.parsedTransformOriginToPercent)(parsed)), [parsed]);
34
+ const parsedZ = (0, react_1.useMemo)(() => (parsed === null || parsed === void 0 ? void 0 : parsed.z) === null || (parsed === null || parsed === void 0 ? void 0 : parsed.z) === undefined
35
+ ? null
36
+ : (0, transform_origin_utils_1.parseTransformOriginZ)(parsed.z), [parsed === null || parsed === void 0 ? void 0 : parsed.z]);
37
+ const show3D = transform3DMode || (parsedZ !== null && parsedZ.value !== 0);
26
38
  const configuredStep = field.fieldSchema.type === 'transform-origin'
27
39
  ? field.fieldSchema.step
28
40
  : undefined;
@@ -37,14 +49,19 @@ const TimelineTransformOriginField = ({ field, propStatus, effectiveValue, onSav
37
49
  value: v,
38
50
  });
39
51
  }, [field.fieldSchema]);
40
- const serialize = (0, react_1.useCallback)((x, y) => {
52
+ const serialize = (0, react_1.useCallback)((x, y, z) => {
41
53
  var _a;
54
+ if (z === void 0) { z = (_a = parsed === null || parsed === void 0 ? void 0 : parsed.z) !== null && _a !== void 0 ? _a : null; }
42
55
  return (0, transform_origin_utils_1.serializeTransformOrigin)({
43
56
  uv: (0, transform_origin_utils_1.transformOriginPercentToUv)([x, y]),
44
- z: (_a = parsed === null || parsed === void 0 ? void 0 : parsed.z) !== null && _a !== void 0 ? _a : null,
57
+ z,
45
58
  decimalPlaces,
46
59
  });
47
60
  }, [decimalPlaces, parsed === null || parsed === void 0 ? void 0 : parsed.z]);
61
+ const serializeZ = (0, react_1.useCallback)((value) => {
62
+ var _a;
63
+ return `${(0, timeline_field_utils_1.normalizeTimelineNumber)(value)}${(_a = parsedZ === null || parsedZ === void 0 ? void 0 : parsedZ.unit) !== null && _a !== void 0 ? _a : 'px'}`;
64
+ }, [parsedZ === null || parsedZ === void 0 ? void 0 : parsedZ.unit]);
48
65
  const onXChange = (0, react_1.useCallback)((newVal) => {
49
66
  if (percent === null) {
50
67
  return;
@@ -127,11 +144,68 @@ const TimelineTransformOriginField = ({ field, propStatus, effectiveValue, onSav
127
144
  }
128
145
  }
129
146
  }, [dragX, onSave, percent, propStatus.codeValue, serialize]);
147
+ const onZChange = (0, react_1.useCallback)((newVal) => {
148
+ if (percent === null) {
149
+ return;
150
+ }
151
+ setDragZ(newVal);
152
+ onDragValueChange(serialize(dragX !== null && dragX !== void 0 ? dragX : percent[0], dragY !== null && dragY !== void 0 ? dragY : percent[1], serializeZ(newVal)));
153
+ }, [dragX, dragY, onDragValueChange, percent, serialize, serializeZ]);
154
+ const onZChangeEnd = (0, react_1.useCallback)((newVal) => {
155
+ if (percent === null) {
156
+ return;
157
+ }
158
+ const value = serialize(dragX !== null && dragX !== void 0 ? dragX : percent[0], dragY !== null && dragY !== void 0 ? dragY : percent[1], serializeZ(newVal));
159
+ if (value !== propStatus.codeValue) {
160
+ onSave(value).finally(() => {
161
+ setDragZ(null);
162
+ onDragEnd();
163
+ });
164
+ }
165
+ else {
166
+ setDragZ(null);
167
+ onDragEnd();
168
+ }
169
+ }, [
170
+ dragX,
171
+ dragY,
172
+ onDragEnd,
173
+ onSave,
174
+ percent,
175
+ propStatus.codeValue,
176
+ serialize,
177
+ serializeZ,
178
+ ]);
179
+ const onZTextChange = (0, react_1.useCallback)((newVal) => {
180
+ if (percent === null) {
181
+ return;
182
+ }
183
+ const parsedValue = Number(newVal);
184
+ if (!Number.isNaN(parsedValue)) {
185
+ const value = serialize(dragX !== null && dragX !== void 0 ? dragX : percent[0], dragY !== null && dragY !== void 0 ? dragY : percent[1], serializeZ(parsedValue));
186
+ if (value !== propStatus.codeValue) {
187
+ setDragZ(parsedValue);
188
+ onSave(value).finally(() => setDragZ(null));
189
+ }
190
+ }
191
+ }, [
192
+ dragX,
193
+ dragY,
194
+ onSave,
195
+ percent,
196
+ propStatus.codeValue,
197
+ serialize,
198
+ serializeZ,
199
+ ]);
130
200
  if (percent === null) {
131
201
  return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "unsupported origin" });
132
202
  }
133
203
  return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
134
- jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : percent[0], style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : percent[1], style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces })
135
- ] }));
204
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : percent[0], buttonStyle: leftDraggerStyle, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, "aria-label": "Transform origin X" }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : percent[1], buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, "aria-label": "Transform origin Y" }), show3D ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
205
+ jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (_a = dragZ !== null && dragZ !== void 0 ? dragZ : parsedZ === null || parsedZ === void 0 ? void 0 : parsedZ.value) !== null && _a !== void 0 ? _a : 0, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onZChange, onValueChangeEnd: onZChangeEnd, onTextChange: onZTextChange, min: -Infinity, max: Infinity, step: step, formatter: (value) => {
206
+ var _a;
207
+ return `${value}${(_a = parsedZ === null || parsedZ === void 0 ? void 0 : parsedZ.unit) !== null && _a !== void 0 ? _a : 'px'}`;
208
+ }, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, "aria-label": "Transform origin Z" })
209
+ ] })) : null] }));
136
210
  };
137
211
  exports.TimelineTransformOriginField = TimelineTransformOriginField;
@@ -7,11 +7,16 @@ const InputDragger_1 = require("../NewComposition/InputDragger");
7
7
  const timeline_field_display_utils_1 = require("./timeline-field-display-utils");
8
8
  const timeline_field_utils_1 = require("./timeline-field-utils");
9
9
  const timeline_translate_utils_1 = require("./timeline-translate-utils");
10
+ const Transform3DModeContext_1 = require("./Transform3DModeContext");
10
11
  const leftDraggerStyle = {
12
+ paddingBottom: 2,
11
13
  paddingLeft: 0,
14
+ paddingTop: 2,
12
15
  };
13
16
  const rightDraggerStyle = {
17
+ paddingBottom: 2,
14
18
  paddingRight: 0,
19
+ paddingTop: 2,
15
20
  };
16
21
  const containerStyle = {
17
22
  display: 'flex',
@@ -19,9 +24,13 @@ const containerStyle = {
19
24
  };
20
25
  const translateDragSensitivity = 3;
21
26
  const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onDragValueChange, onDragEnd, }) => {
27
+ var _a;
22
28
  const [dragX, setDragX] = (0, react_1.useState)(null);
23
29
  const [dragY, setDragY] = (0, react_1.useState)(null);
24
- const [codeX, codeY] = (0, react_1.useMemo)(() => (0, timeline_translate_utils_1.parseTranslate)(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
30
+ const [dragZ, setDragZ] = (0, react_1.useState)(null);
31
+ const transform3DMode = (0, react_1.useContext)(Transform3DModeContext_1.Transform3DModeContext);
32
+ const [codeX, codeY, codeZ] = (0, react_1.useMemo)(() => (0, timeline_translate_utils_1.parseTranslate)(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
33
+ const show3D = transform3DMode || (codeZ !== null && codeZ !== 0);
25
34
  const configuredStep = field.fieldSchema.type === 'translate' ? field.fieldSchema.step : undefined;
26
35
  const step = configuredStep !== null && configuredStep !== void 0 ? configuredStep : 1;
27
36
  const decimalPlaces = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getTimelineDisplayDecimalPlaces)({
@@ -34,15 +43,18 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
34
43
  value: v,
35
44
  });
36
45
  }, [field.fieldSchema]);
46
+ const serialize = (0, react_1.useCallback)((x, y, z = dragZ !== null && dragZ !== void 0 ? dragZ : codeZ) => {
47
+ return (0, timeline_translate_utils_1.serializeTranslate)([x, y, z], decimalPlaces);
48
+ }, [codeZ, decimalPlaces, dragZ]);
37
49
  // --- X callbacks ---
38
50
  const onXChange = (0, react_1.useCallback)((newVal) => {
39
51
  setDragX(newVal);
40
52
  const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
41
- onDragValueChange((0, timeline_translate_utils_1.serializeTranslate)(newVal, currentY, decimalPlaces));
42
- }, [onDragValueChange, dragY, codeY, decimalPlaces]);
53
+ onDragValueChange(serialize(newVal, currentY));
54
+ }, [codeY, dragY, onDragValueChange, serialize]);
43
55
  const onXChangeEnd = (0, react_1.useCallback)((newVal) => {
44
56
  const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
45
- const newStr = (0, timeline_translate_utils_1.serializeTranslate)(newVal, currentY, decimalPlaces);
57
+ const newStr = serialize(newVal, currentY);
46
58
  if (newStr !== propStatus.codeValue) {
47
59
  onSave(newStr).finally(() => {
48
60
  setDragX(null);
@@ -53,12 +65,12 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
53
65
  setDragX(null);
54
66
  onDragEnd();
55
67
  }
56
- }, [dragY, codeY, decimalPlaces, propStatus, onSave, onDragEnd]);
68
+ }, [codeY, dragY, onDragEnd, onSave, propStatus, serialize]);
57
69
  const onXTextChange = (0, react_1.useCallback)((newVal) => {
58
70
  const parsed = Number(newVal);
59
71
  if (!Number.isNaN(parsed)) {
60
72
  const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
61
- const newStr = (0, timeline_translate_utils_1.serializeTranslate)(parsed, currentY, decimalPlaces);
73
+ const newStr = serialize(parsed, currentY);
62
74
  if (newStr !== propStatus.codeValue) {
63
75
  setDragX(parsed);
64
76
  onSave(newStr).finally(() => {
@@ -66,16 +78,16 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
66
78
  });
67
79
  }
68
80
  }
69
- }, [propStatus, dragY, codeY, decimalPlaces, onSave]);
81
+ }, [codeY, dragY, onSave, propStatus, serialize]);
70
82
  // --- Y callbacks ---
71
83
  const onYChange = (0, react_1.useCallback)((newVal) => {
72
84
  setDragY(newVal);
73
85
  const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
74
- onDragValueChange((0, timeline_translate_utils_1.serializeTranslate)(currentX, newVal, decimalPlaces));
75
- }, [onDragValueChange, dragX, codeX, decimalPlaces]);
86
+ onDragValueChange(serialize(currentX, newVal));
87
+ }, [codeX, dragX, onDragValueChange, serialize]);
76
88
  const onYChangeEnd = (0, react_1.useCallback)((newVal) => {
77
89
  const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
78
- const newStr = (0, timeline_translate_utils_1.serializeTranslate)(currentX, newVal, decimalPlaces);
90
+ const newStr = serialize(currentX, newVal);
79
91
  if (newStr !== propStatus.codeValue) {
80
92
  onSave(newStr).finally(() => {
81
93
  setDragY(null);
@@ -86,12 +98,12 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
86
98
  setDragY(null);
87
99
  onDragEnd();
88
100
  }
89
- }, [dragX, codeX, decimalPlaces, propStatus, onSave, onDragEnd]);
101
+ }, [codeX, dragX, onDragEnd, onSave, propStatus, serialize]);
90
102
  const onYTextChange = (0, react_1.useCallback)((newVal) => {
91
103
  const parsed = Number(newVal);
92
104
  if (!Number.isNaN(parsed)) {
93
105
  const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
94
- const newStr = (0, timeline_translate_utils_1.serializeTranslate)(currentX, parsed, decimalPlaces);
106
+ const newStr = serialize(currentX, parsed);
95
107
  if (newStr !== propStatus.codeValue) {
96
108
  setDragY(parsed);
97
109
  onSave(newStr).finally(() => {
@@ -99,9 +111,37 @@ const TimelineTranslateField = ({ field, propStatus, effectiveValue, onSave, onD
99
111
  });
100
112
  }
101
113
  }
102
- }, [propStatus, onSave, dragX, codeX, decimalPlaces]);
114
+ }, [codeX, dragX, onSave, propStatus, serialize]);
115
+ const onZChange = (0, react_1.useCallback)((newVal) => {
116
+ setDragZ(newVal);
117
+ onDragValueChange(serialize(dragX !== null && dragX !== void 0 ? dragX : codeX, dragY !== null && dragY !== void 0 ? dragY : codeY, newVal));
118
+ }, [codeX, codeY, dragX, dragY, onDragValueChange, serialize]);
119
+ const onZChangeEnd = (0, react_1.useCallback)((newVal) => {
120
+ const newStr = serialize(dragX !== null && dragX !== void 0 ? dragX : codeX, dragY !== null && dragY !== void 0 ? dragY : codeY, newVal);
121
+ if (newStr !== propStatus.codeValue) {
122
+ onSave(newStr).finally(() => {
123
+ setDragZ(null);
124
+ onDragEnd();
125
+ });
126
+ }
127
+ else {
128
+ setDragZ(null);
129
+ onDragEnd();
130
+ }
131
+ }, [codeX, codeY, dragX, dragY, onDragEnd, onSave, propStatus, serialize]);
132
+ const onZTextChange = (0, react_1.useCallback)((newVal) => {
133
+ const parsed = Number(newVal);
134
+ if (!Number.isNaN(parsed)) {
135
+ const newStr = serialize(dragX !== null && dragX !== void 0 ? dragX : codeX, dragY !== null && dragY !== void 0 ? dragY : codeY, parsed);
136
+ if (newStr !== propStatus.codeValue) {
137
+ setDragZ(parsed);
138
+ onSave(newStr).finally(() => setDragZ(null));
139
+ }
140
+ }
141
+ }, [codeX, codeY, dragX, dragY, onSave, propStatus, serialize]);
103
142
  return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
104
- jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity })
105
- ] }));
143
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, buttonStyle: leftDraggerStyle, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset X" }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset Y" }), show3D ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
144
+ jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (_a = dragZ !== null && dragZ !== void 0 ? dragZ : codeZ) !== null && _a !== void 0 ? _a : 0, buttonStyle: rightDraggerStyle, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onZChange, onValueChangeEnd: onZChangeEnd, onTextChange: onZTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, snapToStep: false, dragDecimalPlaces: decimalPlaces, dragSensitivity: translateDragSensitivity, "aria-label": "Offset Z" })
145
+ ] })) : null] }));
106
146
  };
107
147
  exports.TimelineTranslateField = TimelineTranslateField;
@@ -0,0 +1 @@
1
+ export declare const Transform3DModeContext: import("react").Context<boolean>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Transform3DModeContext = void 0;
4
+ const react_1 = require("react");
5
+ exports.Transform3DModeContext = (0, react_1.createContext)(false);