@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
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SequenceInspectorSections = exports.SequenceInspectorHeader = exports.useSequenceInspectorSourceLocation = void 0;
3
+ exports.SequenceInspectorSections = exports.SequenceInspectorDuplicationSection = exports.SequenceInspectorHeader = exports.useSequenceInspectorSourceLocation = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const client_id_1 = require("../../helpers/client-id");
@@ -10,7 +10,7 @@ const InspectorInfoHeader_1 = require("../InspectorInfoHeader");
10
10
  const InspectorLocationCopy_1 = require("../InspectorLocationCopy");
11
11
  const InspectorSourceLocation_1 = require("../InspectorSourceLocation");
12
12
  const layout_1 = require("../layout");
13
- const use_open_sequence_in_editor_1 = require("../Timeline/use-open-sequence-in-editor");
13
+ const use_open_sequence_in_apps_1 = require("../Timeline/use-open-sequence-in-apps");
14
14
  const use_rename_sequence_1 = require("../Timeline/use-rename-sequence");
15
15
  const common_1 = require("./common");
16
16
  const ConnectedCompositionsSection_1 = require("./ConnectedCompositionsSection");
@@ -38,7 +38,7 @@ const defaultCursor = {
38
38
  cursor: 'default',
39
39
  };
40
40
  const useSequenceInspectorSourceLocation = (sequence) => {
41
- const { canOpenInEditor, openInEditor, originalLocation } = (0, use_open_sequence_in_editor_1.useOpenSequenceInEditor)(sequence);
41
+ const { canOpenInEditor, openInEditor, originalLocation } = (0, use_open_sequence_in_apps_1.useOpenSequenceInApps)(sequence);
42
42
  const validatedLocation = (0, react_1.useMemo)(() => {
43
43
  var _a;
44
44
  if (!originalLocation ||
@@ -99,11 +99,29 @@ const SequenceInspectorHeader = ({ sourceLocation, track }) => {
99
99
  ] }) }));
100
100
  };
101
101
  exports.SequenceInspectorHeader = SequenceInspectorHeader;
102
+ const SequenceInspectorDuplicationSection = ({ track }) => {
103
+ var _a;
104
+ var _b;
105
+ const numberOfInstances = (_b = (_a = track.nodePathInfo) === null || _a === void 0 ? void 0 : _a.numberOfSequencesWithThisNodePath) !== null && _b !== void 0 ? _b : 0;
106
+ if (numberOfInstances <= 1) {
107
+ return null;
108
+ }
109
+ return (jsx_runtime_1.jsx(common_1.InspectorSection, { header: jsx_runtime_1.jsxs("span", { style: {
110
+ color: 'inherit',
111
+ display: 'block',
112
+ fontFamily: 'inherit',
113
+ fontSize: 'inherit',
114
+ fontWeight: 'normal',
115
+ lineHeight: 'inherit',
116
+ margin: '2px 0',
117
+ }, children: [numberOfInstances, " instances"] }), children: null }));
118
+ };
119
+ exports.SequenceInspectorDuplicationSection = SequenceInspectorDuplicationSection;
102
120
  const SequenceInspectorSections = ({ track }) => {
103
121
  const sourceLocation = (0, exports.useSequenceInspectorSourceLocation)(track.sequence);
104
122
  const connectedCompositions = (0, ConnectedCompositionsSection_1.useConnectedCompositions)({ track });
105
123
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
106
- jsx_runtime_1.jsx(exports.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
124
+ jsx_runtime_1.jsx(exports.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }), jsx_runtime_1.jsx(exports.SequenceInspectorDuplicationSection, { track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
107
125
  jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), jsx_runtime_1.jsx(ConnectedCompositionsSection_1.ConnectedCompositionsSection, { connectedCompositions: connectedCompositions })
108
126
  ] })) : null] }));
109
127
  };
@@ -141,7 +141,7 @@ const SequenceExpandedInspector = ({ track, readOnlyStudio }) => {
141
141
  return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Sequence inspector unavailable" });
142
142
  }
143
143
  return (jsx_runtime_1.jsxs("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, onPointerDown: selectSequenceOnInspectorPointerDown, children: [
144
- jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
144
+ jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }), jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorDuplicationSection, { track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
145
145
  jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), jsx_runtime_1.jsx(ConnectedCompositionsSection_1.ConnectedCompositionsSection, { connectedCompositions: connectedCompositions })
146
146
  ] })) : null, validatedLocation ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx(InspectorSequenceSection_1.InspectorSequenceSection, { sequence: track.sequence, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, renderTransformControls: () => jsx_runtime_1.jsx(AlignmentControls_1.AlignmentControls, { track: track }) }), jsx_runtime_1.jsxs(common_1.InspectorActionSection, { children: [
147
147
  jsx_runtime_1.jsx(SplitSequenceAction, { selection: sequenceSelection, track: track }), jsx_runtime_1.jsx(SequenceSourceActions, { selection: sequenceSelection, track: track, validatedSource: validatedLocation.source })
@@ -43,7 +43,7 @@ exports.sectionHeader = {
43
43
  fontSize: 12,
44
44
  fontWeight: 'bold',
45
45
  lineHeight: '24px',
46
- padding: `4px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
46
+ padding: `4px 0 4px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
47
47
  userSelect: 'none',
48
48
  };
49
49
  exports.inspectorSectionBody = {
@@ -10,9 +10,11 @@ const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
10
10
  const interactivity_enabled_1 = require("../helpers/interactivity-enabled");
11
11
  const timeline_layout_1 = require("../helpers/timeline-layout");
12
12
  const border_radius_1 = require("../icons/border-radius");
13
+ const cube_1 = require("../icons/cube");
13
14
  const fullscreen_1 = require("../icons/fullscreen");
14
15
  const plus_1 = require("../icons/plus");
15
16
  const modals_1 = require("../state/modals");
17
+ const transform_3d_mode_1 = require("../state/transform-3d-mode");
16
18
  const AssetFileIcon_1 = require("./AssetFileIcon");
17
19
  const InlineAction_1 = require("./InlineAction");
18
20
  const InlineCaptionInspector_1 = require("./InlineCaptionInspector");
@@ -27,6 +29,8 @@ const TimelineAssetField_1 = require("./Timeline/TimelineAssetField");
27
29
  const TimelineExpandedRow_1 = require("./Timeline/TimelineExpandedRow");
28
30
  const TimelineRowLayoutContext_1 = require("./Timeline/TimelineRowLayoutContext");
29
31
  const TimelineSelection_1 = require("./Timeline/TimelineSelection");
32
+ const transform_3d_mode_2 = require("./Timeline/transform-3d-mode");
33
+ const Transform3DModeContext_1 = require("./Timeline/Transform3DModeContext");
30
34
  const use_timeline_expanded_tree_1 = require("./Timeline/use-timeline-expanded-tree");
31
35
  const use_select_asset_1 = require("./use-select-asset");
32
36
  const container = {
@@ -56,6 +60,11 @@ const borderRadiusToggleIcon = {
56
60
  height: 15,
57
61
  width: 15,
58
62
  };
63
+ const transform3DToggleIcon = {
64
+ flexShrink: 0,
65
+ height: 14,
66
+ width: 14,
67
+ };
59
68
  const collapsibleSectionHeaderButton = {
60
69
  appearance: 'none',
61
70
  backgroundColor: 'transparent',
@@ -239,6 +248,9 @@ const InspectorSequenceSection = ({ sequence, readOnlyStudio, validatedLocation,
239
248
  const [collapsedKeys, setCollapsedKeys] = (0, react_1.useState)(loadInspectorCollapsedKeys);
240
249
  const [sectionExpansionOverrides, setSectionExpansionOverrides] = (0, react_1.useState)(loadInspectorSectionExpansionOverrides);
241
250
  const [automaticSectionExpansion, setAutomaticSectionExpansion] = (0, react_1.useState)({});
251
+ const { manuallyEnabledSequenceKeys, setManuallyEnabled } = (0, react_1.useContext)(transform_3d_mode_1.Transform3DModeStateContext);
252
+ const sequenceKey = (0, TimelineSelection_1.getTimelineSequenceSelectionKey)(nodePathInfo);
253
+ const manuallyEnabled3DTransform = manuallyEnabledSequenceKeys.has(sequenceKey);
242
254
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
243
255
  const { getDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
244
256
  const { setPropStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
@@ -326,6 +338,22 @@ const InspectorSequenceSection = ({ sequence, readOnlyStudio, validatedLocation,
326
338
  const layoutGroup = controlGroups.find((group) => group.id === 'layout');
327
339
  const controlGroupsWithoutLayout = controlGroups.filter((group) => group.id !== 'layout');
328
340
  const sequencePropStatuses = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePathInfo.sequenceSubscriptionKey);
341
+ const automaticallyEnabled3DTransform = (0, react_1.useMemo)(() => {
342
+ return [
343
+ 'style.translate',
344
+ 'style.scale',
345
+ 'style.rotate',
346
+ 'style.transformOrigin',
347
+ ].some((fieldKey) => (0, transform_3d_mode_2.propStatusHas3DTransformValue)({
348
+ fieldKey,
349
+ propStatus: sequencePropStatuses === null || sequencePropStatuses === void 0 ? void 0 : sequencePropStatuses[fieldKey],
350
+ runtimeValue: runtimeValues[fieldKey],
351
+ }));
352
+ }, [runtimeValues, sequencePropStatuses]);
353
+ const show3DTransformControls = automaticallyEnabled3DTransform || manuallyEnabled3DTransform;
354
+ const onToggle3DTransform = (0, react_1.useCallback)(() => {
355
+ setManuallyEnabled(sequenceKey, !manuallyEnabled3DTransform);
356
+ }, [manuallyEnabled3DTransform, sequenceKey, setManuallyEnabled]);
329
357
  const { schema } = sequence.controls;
330
358
  const getControlGroupActivity = (0, react_1.useCallback)((group) => {
331
359
  if (!(0, inspector_section_collapse_1.isSmartCollapsibleInspectorGroup)(group.id)) {
@@ -476,6 +504,11 @@ const InspectorSequenceSection = ({ sequence, readOnlyStudio, validatedLocation,
476
504
  : borderRadiusUsesShorthand
477
505
  ? 'Use individual corner radii'
478
506
  : 'Use one border radius value', renderAction: (color) => borderRadiusUsesShorthand ? (jsx_runtime_1.jsx(fullscreen_1.FullscreenIcon, { color: color, style: borderRadiusToggleIcon })) : (jsx_runtime_1.jsx(border_radius_1.BorderRadiusIcon, { color: color, style: borderRadiusToggleIcon })) })) : null;
507
+ const transform3DAction = (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, disabled: automaticallyEnabled3DTransform, onClick: onToggle3DTransform, title: automaticallyEnabled3DTransform
508
+ ? '3D controls are required by the current transform values'
509
+ : show3DTransformControls
510
+ ? 'Hide 3D transform controls'
511
+ : 'Show 3D transform controls', hoveredColor: show3DTransformControls ? colors_1.BLUE : undefined, unhoveredColor: show3DTransformControls ? colors_1.BLUE : colors_1.LIGHT_TEXT, renderAction: (color) => (jsx_runtime_1.jsx(cube_1.CubeIcon, { color: color, style: transform3DToggleIcon })) }));
479
512
  const effectsHeader = (jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderRow, children: [
480
513
  jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: "Effects" }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, disabled: !canAddEffect, onClick: onAddEffect, title: canAddEffect ? 'Add effect' : undefined, renderAction: (color) => jsx_runtime_1.jsx(plus_1.Plus, { color: color, style: plusIcon }) })] }));
481
514
  const renderRow = ({ node, depth }) => {
@@ -487,16 +520,15 @@ const InspectorSequenceSection = ({ sequence, readOnlyStudio, validatedLocation,
487
520
  if (collapsible) {
488
521
  return (jsx_runtime_1.jsx(CollapsibleInspectorSectionHeader, { action: group.id === 'border-radius' && expanded ? borderRadiusAction : null, expanded: expanded, label: group.label, onToggle: () => toggleControlGroup(group) }));
489
522
  }
490
- return (jsx_runtime_1.jsx("div", { style: styles_1.sectionHeaderRow, children: jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: group.label }) }));
523
+ return (jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderRow, children: [
524
+ jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: group.label }), group.id === 'transforms' ? transform3DAction : null] }));
491
525
  };
492
526
  if (controlRows.length === 0 &&
493
527
  !showEffectsSection &&
494
528
  inlineCaptions === null) {
495
529
  return (jsx_runtime_1.jsx("div", { style: container, children: jsx_runtime_1.jsx(common_1.InspectorSection, { header: "Controls", children: jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" }) }) }));
496
530
  }
497
- return (jsx_runtime_1.jsx(TimelineAssetField_1.AssetSelectionContext.Provider, { value: assetSelectionContextValue, children: jsx_runtime_1.jsxs("div", { style: container, children: [controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroupsWithoutLayout.map((group) => (jsx_runtime_1.jsx(common_1.InspectorSection, { header: renderControlGroupHeader(group), children: isControlGroupExpanded(group) ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [group.id === 'transforms'
498
- ? renderTransformControls()
499
- : null, group.rows.map(renderRow)] })) : null }, group.id))) })) : null, inlineCaptions ? (jsx_runtime_1.jsx(InlineCaptionInspector_1.InlineCaptionInspector, { captions: inlineCaptions, controls: sequence.controls, nodePath: nodePathInfo.sequenceSubscriptionKey, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation })) : null, showEffectsSection ? (jsx_runtime_1.jsx(common_1.InspectorSection, { header: effectsHeader, children: effectRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) })) : null })) : null, layoutGroup ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: jsx_runtime_1.jsx(common_1.InspectorSection, { header: renderControlGroupHeader(layoutGroup), children: isControlGroupExpanded(layoutGroup)
531
+ return (jsx_runtime_1.jsx(TimelineAssetField_1.AssetSelectionContext.Provider, { value: assetSelectionContextValue, children: jsx_runtime_1.jsxs("div", { style: container, children: [controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroupsWithoutLayout.map((group) => (jsx_runtime_1.jsx(common_1.InspectorSection, { header: renderControlGroupHeader(group), children: isControlGroupExpanded(group) ? (group.id === 'transforms' ? (jsx_runtime_1.jsxs(Transform3DModeContext_1.Transform3DModeContext.Provider, { value: show3DTransformControls, children: [renderTransformControls(), group.rows.map(renderRow)] })) : (group.rows.map(renderRow))) : null }, group.id))) })) : null, inlineCaptions ? (jsx_runtime_1.jsx(InlineCaptionInspector_1.InlineCaptionInspector, { captions: inlineCaptions, controls: sequence.controls, nodePath: nodePathInfo.sequenceSubscriptionKey, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation })) : null, showEffectsSection ? (jsx_runtime_1.jsx(common_1.InspectorSection, { header: effectsHeader, children: effectRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) })) : null })) : null, layoutGroup ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: jsx_runtime_1.jsx(common_1.InspectorSection, { header: renderControlGroupHeader(layoutGroup), children: isControlGroupExpanded(layoutGroup)
500
532
  ? layoutGroup.rows.map(renderRow)
501
533
  : null }) })) : null] }) }));
502
534
  };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const MenuSectionHeader: React.FC<{
3
+ readonly children: string;
4
+ }>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MenuSectionHeader = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const colors_1 = require("../../helpers/colors");
6
+ const sectionHeader = {
7
+ color: colors_1.WHITE_ALPHA_50,
8
+ fontSize: 10,
9
+ lineHeight: '12px',
10
+ paddingBottom: 2,
11
+ paddingLeft: 8,
12
+ paddingRight: 8,
13
+ paddingTop: 6,
14
+ userSelect: 'none',
15
+ WebkitUserSelect: 'none',
16
+ };
17
+ const MenuSectionHeader = ({ children }) => {
18
+ return jsx_runtime_1.jsx("div", { style: sectionHeader, children: children });
19
+ };
20
+ exports.MenuSectionHeader = MenuSectionHeader;
@@ -7,22 +7,33 @@ const mobile_layout_1 = require("../../helpers/mobile-layout");
7
7
  const noop_1 = require("../../helpers/noop");
8
8
  const z_index_1 = require("../../state/z-index");
9
9
  const MenuContent_1 = require("../NewComposition/MenuContent");
10
+ const menu_tree_context_1 = require("./menu-tree-context");
10
11
  const portals_1 = require("./portals");
11
12
  const SubMenuComponent = ({ portalStyle, subMenuActivated, subMenu, onQuitFullMenu, onQuitSubMenu, }) => {
12
13
  const mobileLayout = (0, mobile_layout_1.useMobileLayout)();
14
+ const menuTreeId = (0, react_1.useContext)(menu_tree_context_1.MenuTreeContext);
13
15
  const onOutsideClick = (0, react_1.useCallback)((e) => {
16
+ if (menuTreeId !== null) {
17
+ if ((0, menu_tree_context_1.isNodeInMenuTree)(e, menuTreeId)) {
18
+ onQuitSubMenu();
19
+ }
20
+ else {
21
+ onQuitFullMenu();
22
+ }
23
+ return;
24
+ }
14
25
  if (portals_1.portals.find((p) => p.contains(e)) || mobileLayout) {
15
26
  onQuitSubMenu();
16
27
  }
17
28
  else {
18
29
  onQuitFullMenu();
19
30
  }
20
- }, [mobileLayout, onQuitFullMenu, onQuitSubMenu]);
31
+ }, [menuTreeId, mobileLayout, onQuitFullMenu, onQuitSubMenu]);
21
32
  const onPointerDown = (0, react_1.useCallback)((e) => {
22
33
  // Prevent deselection of currently selected items
23
34
  e.stopPropagation();
24
35
  }, []);
25
- return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onQuitFullMenu, onOutsideClick: onOutsideClick, children: jsx_runtime_1.jsx("div", { style: portalStyle, className: "css-reset", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: onQuitSubMenu, values: subMenu.items, onHide: onQuitFullMenu, leaveLeftSpace: subMenu.leaveLeftSpace, preselectIndex: subMenuActivated === 'without-mouse' &&
36
+ return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onQuitFullMenu, onOutsideClick: onOutsideClick, children: jsx_runtime_1.jsx("div", { "data-remotion-menu-tree-id": menuTreeId !== null && menuTreeId !== void 0 ? menuTreeId : undefined, style: portalStyle, className: "css-reset", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: onQuitSubMenu, values: subMenu.items, onHide: onQuitFullMenu, leaveLeftSpace: subMenu.leaveLeftSpace, preselectIndex: subMenuActivated === 'without-mouse' &&
26
37
  typeof subMenu.preselectIndex === 'number'
27
38
  ? subMenu.preselectIndex
28
39
  : false, topItemCanBeUnselected: false, fixedHeight: null }) }) }));
@@ -0,0 +1,3 @@
1
+ export declare const getNextMenuTreeId: () => number;
2
+ export declare const MenuTreeContext: import("react").Context<number | null>;
3
+ export declare const isNodeInMenuTree: (node: Node, menuTreeId: number) => boolean;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isNodeInMenuTree = exports.MenuTreeContext = exports.getNextMenuTreeId = void 0;
4
+ const react_1 = require("react");
5
+ let nextMenuTreeId = 0;
6
+ const getNextMenuTreeId = () => nextMenuTreeId++;
7
+ exports.getNextMenuTreeId = getNextMenuTreeId;
8
+ exports.MenuTreeContext = (0, react_1.createContext)(null);
9
+ const isNodeInMenuTree = (node, menuTreeId) => {
10
+ const element = node instanceof Element ? node : node.parentElement;
11
+ return ((element === null || element === void 0 ? void 0 : element.closest(`[data-remotion-menu-tree-id="${menuTreeId}"]`)) !== null);
12
+ };
13
+ exports.isNodeInMenuTree = isNodeInMenuTree;
@@ -48,7 +48,7 @@ const MenuBuildIndicator = ({ mobileLayout }) => {
48
48
  };
49
49
  }, []);
50
50
  return (jsx_runtime_1.jsxs("div", { style: cwd, title: window.remotion_cwd, children: [
51
- jsx_runtime_1.jsx(layout_1.Spacing, { x: mobileLayout ? 0.5 : 2 }), window.remotion_projectName, jsx_runtime_1.jsx(MenuCompositionName_1.MenuCompositionName, {}), jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { location: folderLocation }), mobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), mobileLayout ? (isBuilding ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
51
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: mobileLayout ? 0.5 : 2 }), window.remotion_projectName, jsx_runtime_1.jsx(MenuCompositionName_1.MenuCompositionName, {}), jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { location: folderLocation, locationType: "folder" }), mobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), mobileLayout ? (isBuilding ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
52
52
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx("div", { style: spinner, children: jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: spinnerSize, color: colors_1.WHITE_ALPHA_80 }) })
53
53
  ] })) : null) : isBuilding ? (jsx_runtime_1.jsx("div", { style: spinner, children: jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: spinnerSize, color: colors_1.WHITE_ALPHA_80 }) })) : (jsx_runtime_1.jsx("div", { style: noSpinner }))] }));
54
54
  };
@@ -4,6 +4,11 @@ type DividerItem = {
4
4
  type: 'divider';
5
5
  id: string;
6
6
  };
7
+ type SectionHeaderItem = {
8
+ type: 'section-header';
9
+ id: string;
10
+ label: string;
11
+ };
7
12
  export type SubMenu = {
8
13
  preselectIndex: number | false;
9
14
  leaveLeftSpace: boolean;
@@ -21,7 +26,7 @@ export type SelectionItem = {
21
26
  quickSwitcherLabel: string | null;
22
27
  disabled?: boolean;
23
28
  };
24
- export type ComboboxValue = DividerItem | SelectionItem;
29
+ export type ComboboxValue = DividerItem | SectionHeaderItem | SelectionItem;
25
30
  export declare const Combobox: React.FC<{
26
31
  readonly values: ComboboxValue[];
27
32
  readonly selectedId: string | number;
@@ -8,7 +8,9 @@ const mobile_layout_1 = require("../../helpers/mobile-layout");
8
8
  const studio_runtime_config_1 = require("../../helpers/studio-runtime-config");
9
9
  const use_keybinding_1 = require("../../helpers/use-keybinding");
10
10
  const is_menu_item_1 = require("../Menu/is-menu-item");
11
+ const menu_tree_context_1 = require("../Menu/menu-tree-context");
11
12
  const MenuDivider_1 = require("../Menu/MenuDivider");
13
+ const MenuSectionHeader_1 = require("../Menu/MenuSectionHeader");
12
14
  const MenuSubItem_1 = require("../Menu/MenuSubItem");
13
15
  const styles_1 = require("../Menu/styles");
14
16
  const menu_typeahead_1 = require("./menu-typeahead");
@@ -27,6 +29,9 @@ const container = {
27
29
  const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMenu, leaveLeftSpace, topItemCanBeUnselected, fixedHeight, }) => {
28
30
  const keybindings = (0, use_keybinding_1.useKeybinding)();
29
31
  const containerRef = (0, react_1.useRef)(null);
32
+ const inheritedMenuTreeId = (0, react_1.useContext)(menu_tree_context_1.MenuTreeContext);
33
+ const localMenuTreeId = (0, react_1.useRef)((0, menu_tree_context_1.getNextMenuTreeId)());
34
+ const menuTreeId = inheritedMenuTreeId !== null && inheritedMenuTreeId !== void 0 ? inheritedMenuTreeId : localMenuTreeId.current;
30
35
  const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
31
36
  const [subMenuActivated, setSubMenuActivated] = (0, react_1.useState)(false);
32
37
  const typeaheadQueryRef = (0, react_1.useRef)('');
@@ -51,7 +56,7 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
51
56
  }
52
57
  }, []);
53
58
  const isItemSelectable = (0, react_1.useCallback)((v) => {
54
- return v.type !== 'divider' && !v.disabled;
59
+ return v.type === 'item' && !v.disabled;
55
60
  }, []);
56
61
  const onArrowUp = (0, react_1.useCallback)(() => {
57
62
  setSelectedItem((prevItem) => {
@@ -98,8 +103,8 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
98
103
  if (!item) {
99
104
  throw new Error('cannot find item');
100
105
  }
101
- if (item.type === 'divider') {
102
- throw new Error('cannot find divider');
106
+ if (item.type !== 'item') {
107
+ throw new Error('cannot select non-interactive menu item');
103
108
  }
104
109
  if (item.disabled) {
105
110
  return;
@@ -118,8 +123,8 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
118
123
  if (!item) {
119
124
  throw new Error('cannot find item');
120
125
  }
121
- if (item.type === 'divider') {
122
- throw new Error('cannot find divider');
126
+ if (item.type !== 'item') {
127
+ throw new Error('cannot select non-interactive menu item');
123
128
  }
124
129
  if (!item.subMenu) {
125
130
  return onNextMenu();
@@ -282,8 +287,8 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
282
287
  // Can happen if resizing the window
283
288
  return;
284
289
  }
285
- if (item.type === 'divider') {
286
- throw new Error('should not select divider');
290
+ if (item.type !== 'item') {
291
+ throw new Error('should not select non-interactive menu item');
287
292
  }
288
293
  if (!item.subMenu && subMenuActivated) {
289
294
  setSubMenuActivated(false);
@@ -303,18 +308,21 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
303
308
  current.addEventListener('pointerleave', onPointerLeave);
304
309
  return () => current.removeEventListener('pointerleave', onPointerLeave);
305
310
  }, [onHide, subMenuActivated]);
306
- return (jsx_runtime_1.jsx("div", { ref: containerRef, style: containerWithHeight, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: values.map((item) => {
307
- if (item.type === 'divider') {
308
- return jsx_runtime_1.jsx(MenuDivider_1.MenuDivider, {}, item.id);
309
- }
310
- const onClick = (id, e) => {
311
- item.onClick(id, e);
312
- if (item.subMenu) {
313
- return null;
311
+ return (jsx_runtime_1.jsx(menu_tree_context_1.MenuTreeContext.Provider, { value: menuTreeId, children: jsx_runtime_1.jsx("div", { ref: containerRef, "data-remotion-menu-tree-id": menuTreeId, style: containerWithHeight, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: values.map((item) => {
312
+ if (item.type === 'divider') {
313
+ return jsx_runtime_1.jsx(MenuDivider_1.MenuDivider, {}, item.id);
314
+ }
315
+ if (item.type === 'section-header') {
316
+ return (jsx_runtime_1.jsx(MenuSectionHeader_1.MenuSectionHeader, { children: item.label }, item.id));
314
317
  }
315
- onHide();
316
- };
317
- return (jsx_runtime_1.jsx(MenuSubItem_1.MenuSubItem, { selected: item.id === selectedItem, onActionChosen: onClick, onItemSelected: onItemSelected, label: item.label, id: item.id, keyHint: item.keyHint, leaveLeftSpace: leaveLeftSpace, leftItem: item.leftItem, subMenu: item.subMenu, onQuitMenu: onHide, onNextMenu: onNextMenu, subMenuActivated: subMenuActivated, setSubMenuActivated: setSubMenuActivated, disabled: item.disabled }, item.id));
318
- }) }));
318
+ const onClick = (id, e) => {
319
+ item.onClick(id, e);
320
+ if (item.subMenu) {
321
+ return null;
322
+ }
323
+ onHide();
324
+ };
325
+ return (jsx_runtime_1.jsx(MenuSubItem_1.MenuSubItem, { selected: item.id === selectedItem, onActionChosen: onClick, onItemSelected: onItemSelected, label: item.label, id: item.id, keyHint: item.keyHint, leaveLeftSpace: leaveLeftSpace, leftItem: item.leftItem, subMenu: item.subMenu, onQuitMenu: onHide, onNextMenu: onNextMenu, subMenuActivated: subMenuActivated, setSubMenuActivated: setSubMenuActivated, disabled: item.disabled }, item.id));
326
+ }) }) }));
319
327
  };
320
328
  exports.MenuContent = MenuContent;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findTypeaheadMenuItem = void 0;
4
4
  const getLabelToMatch = (value) => {
5
- if (value.type === 'divider' || value.disabled) {
5
+ if (value.type !== 'item' || value.disabled) {
6
6
  return null;
7
7
  }
8
8
  if (typeof value.label === 'string') {
@@ -19,7 +19,7 @@ const findTypeaheadMenuItem = ({ query, values, }) => {
19
19
  const label = getLabelToMatch(value);
20
20
  return label ? label.toLowerCase().startsWith(normalizedQuery) : false;
21
21
  });
22
- if (!matched || matched.type === 'divider') {
22
+ if (!matched || matched.type !== 'item') {
23
23
  return null;
24
24
  }
25
25
  return matched.id;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- export declare const PlayPause: React.FC<{
2
+ export declare const PlayPause: React.NamedExoticComponent<{
3
3
  readonly playbackRate: number;
4
4
  readonly loop: boolean;
5
5
  readonly bufferStateDelayInMilliseconds: number;
@@ -1,9 +1,42 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.PlayPause = void 0;
4
37
  const jsx_runtime_1 = require("react/jsx-runtime");
5
38
  const player_1 = require("@remotion/player");
6
- const react_1 = require("react");
39
+ const react_1 = __importStar(require("react"));
7
40
  const remotion_1 = require("remotion");
8
41
  const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
9
42
  const use_keybinding_1 = require("../helpers/use-keybinding");
@@ -26,12 +59,10 @@ const iconButton = {
26
59
  height: 14,
27
60
  width: 14,
28
61
  };
29
- const PlayPause = ({ playbackRate, loop, bufferStateDelayInMilliseconds, muted, hideNavigationControls, }) => {
30
- const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
31
- const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
32
- const [showBufferIndicator, setShowBufferState] = (0, react_1.useState)(false);
33
- const { play, pause, pauseAndReturnToPlayStart, frameBack, seek, frameForward, emitter, getCurrentFrame, } = player_1.PlayerInternals.usePlayerMethods();
34
- const [playing] = remotion_1.Internals.Timeline.usePlayingState();
62
+ const browserMediaControlsBehavior = {
63
+ mode: 'register-media-session',
64
+ };
65
+ const PlaybackManager = ({ playbackRate, loop, muted, inFrame, outFrame, getCurrentFrame }) => {
35
66
  player_1.PlayerInternals.usePlayback({
36
67
  loop,
37
68
  playbackRate,
@@ -39,11 +70,28 @@ const PlayPause = ({ playbackRate, loop, bufferStateDelayInMilliseconds, muted,
39
70
  inFrame,
40
71
  outFrame,
41
72
  getCurrentFrame,
42
- browserMediaControlsBehavior: {
43
- mode: 'register-media-session',
44
- },
73
+ browserMediaControlsBehavior,
45
74
  muted,
46
75
  });
76
+ return null;
77
+ };
78
+ const PlayPauseInner = ({ playbackRate, loop, bufferStateDelayInMilliseconds, muted, hideNavigationControls, }) => {
79
+ const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
80
+ const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
81
+ const [showBufferIndicator, setShowBufferState] = (0, react_1.useState)(false);
82
+ const { play, pause, pauseAndReturnToPlayStart, frameBack, seek, frameForward, emitter, getCurrentFrame, isPlaying, } = player_1.PlayerInternals.usePlayerMethods();
83
+ const [playing, setPlaying] = (0, react_1.useState)(isPlaying);
84
+ (0, react_1.useEffect)(() => {
85
+ const onPlay = () => setPlaying(true);
86
+ const onPause = () => setPlaying(false);
87
+ setPlaying(isPlaying());
88
+ emitter.addEventListener('play', onPlay);
89
+ emitter.addEventListener('pause', onPause);
90
+ return () => {
91
+ emitter.removeEventListener('play', onPlay);
92
+ emitter.removeEventListener('pause', onPause);
93
+ };
94
+ }, [emitter, isPlaying]);
47
95
  const isStill = (0, is_current_selected_still_1.useIsStill)();
48
96
  (0, react_1.useEffect)(() => {
49
97
  if (isStill) {
@@ -195,6 +243,7 @@ const PlayPause = ({ playbackRate, loop, bufferStateDelayInMilliseconds, muted,
195
243
  stopped = true;
196
244
  };
197
245
  }, [bufferStateDelayInMilliseconds, emitter]);
198
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Jump to beginning", title: "Jump to beginning", disabled: !videoConfig, onClick: jumpToStart, children: (color) => jsx_runtime_1.jsx(jump_to_start_1.JumpToStart, { style: backStyle, color: color }) })), hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Step back one frame", title: "Step back one frame", disabled: !videoConfig, onClick: oneFrameBack, children: (color) => jsx_runtime_1.jsx(step_back_1.StepBack, { style: forwardBackStyle, color: color }) })), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": playing ? 'Pause' : 'Play', title: playing ? 'Pause' : 'Play', onClick: playing ? pause : play, disabled: !videoConfig, children: (color) => playing ? (showBufferIndicator ? (jsx_runtime_1.jsx(player_1.PlayerInternals.BufferingIndicator, { type: "studio", color: color })) : (jsx_runtime_1.jsx(pause_1.Pause, { style: iconButton, color: color }))) : (jsx_runtime_1.jsx(play_1.Play, { style: iconButton, color: color })) }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Step forward one frame", title: "Step forward one frame", disabled: !videoConfig, onClick: oneFrameForward, children: (color) => jsx_runtime_1.jsx(step_forward_1.StepForward, { style: forwardBackStyle, color: color }) }))] }));
246
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
247
+ jsx_runtime_1.jsx(PlaybackManager, { loop: loop, playbackRate: playbackRate, muted: muted, inFrame: inFrame, outFrame: outFrame, getCurrentFrame: getCurrentFrame }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Jump to beginning", title: "Jump to beginning", disabled: !videoConfig, onClick: jumpToStart, children: (color) => jsx_runtime_1.jsx(jump_to_start_1.JumpToStart, { style: backStyle, color: color }) })), hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Step back one frame", title: "Step back one frame", disabled: !videoConfig, onClick: oneFrameBack, children: (color) => jsx_runtime_1.jsx(step_back_1.StepBack, { style: forwardBackStyle, color: color }) })), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": playing ? 'Pause' : 'Play', title: playing ? 'Pause' : 'Play', onClick: playing ? pause : play, disabled: !videoConfig, children: (color) => playing ? (showBufferIndicator ? (jsx_runtime_1.jsx(player_1.PlayerInternals.BufferingIndicator, { type: "studio", color: color })) : (jsx_runtime_1.jsx(pause_1.Pause, { style: iconButton, color: color }))) : (jsx_runtime_1.jsx(play_1.Play, { style: iconButton, color: color })) }), hideNavigationControls ? null : (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { "aria-label": "Step forward one frame", title: "Step forward one frame", disabled: !videoConfig, onClick: oneFrameForward, children: (color) => jsx_runtime_1.jsx(step_forward_1.StepForward, { style: forwardBackStyle, color: color }) }))] }));
199
248
  };
200
- exports.PlayPause = PlayPause;
249
+ exports.PlayPause = react_1.default.memo(PlayPauseInner);
@@ -69,6 +69,24 @@ const VideoPreview = ({ canvasSize, contentDimensions, canvasContent, assetMetad
69
69
  exports.VideoPreview = VideoPreview;
70
70
  const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent, assetMetadata }) => {
71
71
  const { size: previewSize } = (0, react_1.useContext)(remotion_1.Internals.PreviewSizeContext);
72
+ const [canvasHovered, setCanvasHovered] = (0, react_1.useState)(false);
73
+ const compositionContainerRef = (0, react_1.useRef)(null);
74
+ (0, react_1.useEffect)(() => {
75
+ const compositionContainer = compositionContainerRef.current;
76
+ if (compositionContainer === null) {
77
+ setCanvasHovered(false);
78
+ return;
79
+ }
80
+ const onPointerEnter = () => setCanvasHovered(true);
81
+ const onPointerLeave = () => setCanvasHovered(false);
82
+ setCanvasHovered(compositionContainer.matches(':hover'));
83
+ compositionContainer.addEventListener('pointerenter', onPointerEnter);
84
+ compositionContainer.addEventListener('pointerleave', onPointerLeave);
85
+ return () => {
86
+ compositionContainer.removeEventListener('pointerenter', onPointerEnter);
87
+ compositionContainer.removeEventListener('pointerleave', onPointerLeave);
88
+ };
89
+ }, [canvasContent.type]);
72
90
  const { centerX, centerY, yCorrection, xCorrection, scale } = (0, react_1.useMemo)(() => {
73
91
  if (contentDimensions === 'none') {
74
92
  return {
@@ -129,8 +147,8 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
129
147
  if (canvasContent.type === 'output-blob') {
130
148
  return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(RenderPreview_1.RenderPreview, { path: canvasContent.displayName, assetMetadata: assetMetadata, getBlob: canvasContent.getBlob }) }));
131
149
  }
132
- return (jsx_runtime_1.jsxs("div", { className: "remotion-studio-composition-container", style: outer, children: [
133
- jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { compositionHeight: contentDimensions.height, compositionWidth: contentDimensions.width, scale: scale, translationX: previewSize.translation.x, translationY: previewSize.translation.y })
150
+ return (jsx_runtime_1.jsxs("div", { ref: compositionContainerRef, className: "remotion-studio-composition-container", style: outer, children: [
151
+ jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { canvasHovered: canvasHovered, compositionHeight: contentDimensions.height, compositionWidth: contentDimensions.width, scale: scale, translationX: previewSize.translation.x, translationY: previewSize.translation.y })
134
152
  ] }));
135
153
  };
136
154
  const PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions }) => {
@@ -154,13 +172,20 @@ const PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions })
154
172
  xCorrection,
155
173
  yCorrection,
156
174
  ]);
157
- (0, react_1.useEffect)(() => {
175
+ (0, react_1.useLayoutEffect)(() => {
158
176
  const { current } = portalContainer;
159
177
  current === null || current === void 0 ? void 0 : current.appendChild(remotion_1.Internals.portalNode());
160
178
  return () => {
161
- current === null || current === void 0 ? void 0 : current.removeChild(remotion_1.Internals.portalNode());
179
+ const portalNode = remotion_1.Internals.portalNode();
180
+ if (current && portalNode.parentNode === current) {
181
+ current.removeChild(portalNode);
182
+ remotion_1.Internals.setPortalNodeCurrentScale(1);
183
+ }
162
184
  };
163
185
  }, []);
186
+ (0, react_1.useLayoutEffect)(() => {
187
+ remotion_1.Internals.setPortalNodeCurrentScale(scale);
188
+ }, [scale]);
164
189
  const onPointerDown = (0, react_1.useCallback)((event) => {
165
190
  if (!(0, should_clear_selection_on_pointer_down_1.shouldClearSelectionOnPointerDown)(event)) {
166
191
  return;
@@ -390,17 +390,21 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
390
390
  ];
391
391
  }
392
392
  return [
393
- {
394
- type: 'item',
395
- id: 'server-render',
396
- label: 'Server-side render',
397
- value: 'server-render',
398
- onClick: () => handleRenderTypeChange('server-render'),
399
- keyHint: null,
400
- leftItem: null,
401
- subMenu: null,
402
- quickSwitcherLabel: null,
403
- },
393
+ ...(canServerRender
394
+ ? [
395
+ {
396
+ type: 'item',
397
+ id: 'server-render',
398
+ label: 'Server-side render',
399
+ value: 'server-render',
400
+ onClick: () => handleRenderTypeChange('server-render'),
401
+ keyHint: null,
402
+ leftItem: null,
403
+ subMenu: null,
404
+ quickSwitcherLabel: null,
405
+ },
406
+ ]
407
+ : []),
404
408
  {
405
409
  type: 'item',
406
410
  id: 'client-render',
@@ -413,7 +417,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
413
417
  quickSwitcherLabel: null,
414
418
  },
415
419
  ];
416
- }, [handleRenderTypeChange, readOnlyStudio]);
420
+ }, [canServerRender, handleRenderTypeChange, readOnlyStudio]);
417
421
  const spaceToBottom = (0, react_1.useMemo)(() => {
418
422
  const margin = 10;
419
423
  if (size && dropdownOpened) {