@remotion/studio 4.0.507 → 4.0.509

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 (191) hide show
  1. package/dist/FastRefreshProvider.js +13 -9
  2. package/dist/Studio.d.ts +5 -0
  3. package/dist/Studio.js +2 -2
  4. package/dist/components/Canvas.js +35 -5
  5. package/dist/components/CodingAgentIcon.d.ts +3 -1
  6. package/dist/components/CodingAgentIcon.js +4 -9
  7. package/dist/components/ColorPicker/AlphaSlider.js +2 -2
  8. package/dist/components/ColorPicker/HueSlider.js +2 -2
  9. package/dist/components/ColorPicker/SaturationValueArea.js +2 -2
  10. package/dist/components/ConfigureDefaultEditorModal.js +1 -1
  11. package/dist/components/ContextMenu.d.ts +1 -0
  12. package/dist/components/ContextMenu.js +32 -5
  13. package/dist/components/EditorContent.js +4 -3
  14. package/dist/components/EditorGuides/Guide.js +2 -2
  15. package/dist/components/EditorRuler/index.js +2 -2
  16. package/dist/components/ExplorerPanel.js +19 -1
  17. package/dist/components/InlineAction.d.ts +2 -1
  18. package/dist/components/InlineAction.js +3 -3
  19. package/dist/components/InspectorLocationCopy.js +1 -1
  20. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  21. package/dist/components/InspectorOpenInEditor.js +52 -8
  22. package/dist/components/InspectorPanel/AlignmentControls.js +2 -2
  23. package/dist/components/InspectorPanel/CompositionInspector.js +3 -1
  24. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +3 -3
  25. package/dist/components/InspectorPanel/styles.js +1 -1
  26. package/dist/components/InspectorSequenceSection.js +36 -4
  27. package/dist/components/Menu/MenuItem.js +2 -2
  28. package/dist/components/MenuBuildIndicator.js +1 -1
  29. package/dist/components/ModalContainer.js +1 -1
  30. package/dist/components/Modals.js +2 -9
  31. package/dist/components/NewComposition/InputDragger.js +2 -2
  32. package/dist/components/NewComposition/NewComposition.d.ts +2 -0
  33. package/dist/components/NewComposition/NewComposition.js +38 -6
  34. package/dist/components/NewComposition/get-new-composition-defaults.d.ts +1 -1
  35. package/dist/components/NewComposition/get-new-composition-defaults.js +9 -1
  36. package/dist/components/PlayPause.d.ts +1 -1
  37. package/dist/components/PlayPause.js +61 -12
  38. package/dist/components/RenderButton.js +16 -12
  39. package/dist/components/RenderModal/GuiRenderStatus.js +23 -6
  40. package/dist/components/RenderModal/InfoBubble.d.ts +1 -0
  41. package/dist/components/RenderModal/InfoBubble.js +6 -4
  42. package/dist/components/RenderModal/InfoTooltip.d.ts +1 -0
  43. package/dist/components/RenderModal/InfoTooltip.js +12 -12
  44. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.d.ts +5 -0
  45. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +16 -3
  46. package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.js +1 -1
  47. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.d.ts +2 -0
  48. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.js +3 -2
  49. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +1 -1
  50. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +1 -1
  51. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +2 -1
  52. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +1 -1
  53. package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.js +1 -1
  54. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +1 -1
  55. package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.js +1 -1
  56. package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.js +1 -1
  57. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +6 -1
  58. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +1 -1
  59. package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.js +1 -1
  60. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +1 -1
  61. package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.js +1 -1
  62. package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.js +1 -1
  63. package/dist/components/RenderModal/SchemaEditor/zod-schema-type.d.ts +1 -0
  64. package/dist/components/RenderModal/SchemaEditor/zod-schema-type.js +12 -1
  65. package/dist/components/SelectedOutlineCanvasRotation.d.ts +9 -0
  66. package/dist/components/SelectedOutlineCanvasRotation.js +239 -0
  67. package/dist/components/SelectedOutlineCropControls.js +2 -2
  68. package/dist/components/SelectedOutlineElement.d.ts +2 -1
  69. package/dist/components/SelectedOutlineElement.js +40 -5
  70. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  71. package/dist/components/SelectedOutlineOverlay.js +55 -26
  72. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  73. package/dist/components/SelectedOutlinePolygon.js +6 -5
  74. package/dist/components/SelectedOutlineRenderer.d.ts +1 -0
  75. package/dist/components/SelectedOutlineRenderer.js +24 -7
  76. package/dist/components/SelectedOutlineRotationCornerHandle.d.ts +6 -0
  77. package/dist/components/SelectedOutlineRotationCornerHandle.js +9 -7
  78. package/dist/components/SelectedOutlineScaleEdgeLine.d.ts +2 -0
  79. package/dist/components/SelectedOutlineScaleEdgeLine.js +11 -7
  80. package/dist/components/SelectedOutlineTransformOriginHandle.js +50 -24
  81. package/dist/components/SelectedOutlineUvControls.js +8 -8
  82. package/dist/components/SequencePropsSubscriptionProvider.js +8 -0
  83. package/dist/components/SettingsModalFooter.js +1 -1
  84. package/dist/components/Splitter/SplitterHandle.js +2 -2
  85. package/dist/components/Tabs/index.d.ts +2 -0
  86. package/dist/components/Tabs/index.js +2 -2
  87. package/dist/components/Timeline/EasingEditorModal.js +2 -2
  88. package/dist/components/Timeline/SequencePropsObserver.js +97 -1
  89. package/dist/components/Timeline/SubscribeToNodePaths.js +4 -2
  90. package/dist/components/Timeline/Timeline.js +55 -1
  91. package/dist/components/Timeline/TimelineClipboardKeybindings.js +99 -35
  92. package/dist/components/Timeline/TimelineDragHandler.js +2 -2
  93. package/dist/components/Timeline/TimelineEffectItem.js +1 -4
  94. package/dist/components/Timeline/TimelineEffectPropItem.js +7 -0
  95. package/dist/components/Timeline/TimelineFieldRowContent.js +10 -3
  96. package/dist/components/Timeline/TimelineInOutDragHandler.js +2 -2
  97. package/dist/components/Timeline/TimelineLayerEye.js +2 -2
  98. package/dist/components/Timeline/TimelineRotationField.js +84 -12
  99. package/dist/components/Timeline/TimelineScaleField.js +58 -4
  100. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  101. package/dist/components/Timeline/TimelineSelection.js +47 -4
  102. package/dist/components/Timeline/TimelineSequenceItem.js +43 -25
  103. package/dist/components/Timeline/TimelineSequencePropItem.js +12 -3
  104. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +6 -6
  105. package/dist/components/Timeline/TimelineTransformOriginField.js +78 -4
  106. package/dist/components/Timeline/TimelineTranslateField.js +55 -15
  107. package/dist/components/Timeline/Transform3DModeContext.d.ts +1 -0
  108. package/dist/components/Timeline/Transform3DModeContext.js +5 -0
  109. package/dist/components/Timeline/delete-selected-timeline-item.js +0 -6
  110. package/dist/components/Timeline/get-sequence-context-menu-items.js +14 -6
  111. package/dist/components/Timeline/keyframe-clipboard.d.ts +5 -1
  112. package/dist/components/Timeline/keyframe-clipboard.js +3 -2
  113. package/dist/components/Timeline/save-sequence-prop.js +16 -7
  114. package/dist/components/Timeline/sequence-prop-clipboard.d.ts +31 -0
  115. package/dist/components/Timeline/sequence-prop-clipboard.js +142 -0
  116. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
  117. package/dist/components/Timeline/sequence-props-subscription-store.js +5 -2
  118. package/dist/components/Timeline/timeline-field-display-utils.js +2 -2
  119. package/dist/components/Timeline/timeline-field-row-layout.d.ts +6 -0
  120. package/dist/components/Timeline/timeline-field-row-layout.js +16 -1
  121. package/dist/components/Timeline/timeline-rotation-utils.d.ts +16 -0
  122. package/dist/components/Timeline/timeline-rotation-utils.js +145 -4
  123. package/dist/components/Timeline/timeline-translate-utils.d.ts +3 -2
  124. package/dist/components/Timeline/timeline-translate-utils.js +8 -4
  125. package/dist/components/Timeline/transform-3d-mode.d.ts +6 -0
  126. package/dist/components/Timeline/transform-3d-mode.js +36 -0
  127. package/dist/components/Timeline/transform-origin-utils.d.ts +4 -0
  128. package/dist/components/Timeline/transform-origin-utils.js +12 -6
  129. package/dist/components/Timeline/update-selected-easing.js +8 -0
  130. package/dist/components/Timeline/use-open-sequence-in-apps.js +3 -1
  131. package/dist/components/Timeline/use-resolved-stack-react-to-change.d.ts +5 -1
  132. package/dist/components/Timeline/use-resolved-stack-react-to-change.js +67 -10
  133. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -1
  134. package/dist/components/Timeline/use-sequence-props-subscription.js +7 -2
  135. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  136. package/dist/components/call-api.js +2 -0
  137. package/dist/components/canvas-rotation-cursor.d.ts +1 -0
  138. package/dist/components/canvas-rotation-cursor.js +14 -0
  139. package/dist/components/folder-menu-items.js +1 -0
  140. package/dist/components/get-open-in-menu-items.d.ts +8 -1
  141. package/dist/components/get-open-in-menu-items.js +93 -8
  142. package/dist/components/import-assets.js +7 -0
  143. package/dist/components/root-composition-menu-items.js +1 -0
  144. package/dist/components/selected-outline-control-layout.d.ts +14 -0
  145. package/dist/components/selected-outline-control-layout.js +94 -0
  146. package/dist/components/selected-outline-drag.d.ts +11 -5
  147. package/dist/components/selected-outline-drag.js +80 -42
  148. package/dist/components/selected-outline-measurement.d.ts +5 -0
  149. package/dist/components/selected-outline-measurement.js +28 -1
  150. package/dist/components/selected-outline-types.d.ts +6 -0
  151. package/dist/components/use-default-editor-info.js +28 -3
  152. package/dist/esm/{chunk-ptnd65a9.js → chunk-jdn6nkbk.js} +10087 -7919
  153. package/dist/esm/{chunk-fgedsvhb.js → chunk-r46yxrjr.js} +1 -2
  154. package/dist/esm/index.mjs +357 -2
  155. package/dist/esm/internals.mjs +10086 -7918
  156. package/dist/esm/previewEntry.mjs +9926 -7758
  157. package/dist/esm/renderEntry.mjs +4 -2
  158. package/dist/helpers/get-box-quads-polyfill-internals.js +10 -2
  159. package/dist/helpers/get-canvas-capture-import.d.ts +7 -0
  160. package/dist/helpers/get-canvas-capture-import.js +43 -0
  161. package/dist/helpers/get-git-menu-item.d.ts +1 -1
  162. package/dist/helpers/get-git-menu-item.js +33 -3
  163. package/dist/helpers/inserted-element-selection.d.ts +12 -0
  164. package/dist/helpers/inserted-element-selection.js +29 -0
  165. package/dist/helpers/open-in-editor.d.ts +3 -1
  166. package/dist/helpers/open-in-editor.js +5 -1
  167. package/dist/helpers/pointer-session.d.ts +6 -2
  168. package/dist/helpers/pointer-session.js +29 -12
  169. package/dist/helpers/preview-server-events.js +4 -0
  170. package/dist/helpers/sequence-node-path-mutations.d.ts +4 -0
  171. package/dist/helpers/sequence-node-path-mutations.js +31 -0
  172. package/dist/helpers/use-create-composition.d.ts +15 -2
  173. package/dist/helpers/use-create-composition.js +11 -17
  174. package/dist/helpers/use-menu-structure.js +1 -0
  175. package/dist/icons/cube.d.ts +4 -0
  176. package/dist/icons/cube.js +6 -0
  177. package/dist/icons/finder.d.ts +4 -0
  178. package/dist/icons/finder.js +8 -0
  179. package/dist/icons/github.d.ts +4 -0
  180. package/dist/icons/github.js +11 -0
  181. package/dist/icons/terminal.d.ts +6 -0
  182. package/dist/icons/terminal.js +46 -0
  183. package/dist/index.d.ts +15 -0
  184. package/dist/index.js +8 -0
  185. package/dist/renderEntry.js +2 -2
  186. package/dist/state/modals.d.ts +9 -1
  187. package/dist/state/transform-3d-mode.d.ts +10 -0
  188. package/dist/state/transform-3d-mode.js +27 -0
  189. package/dist/state/z-index.d.ts +0 -1
  190. package/dist/state/z-index.js +28 -37
  191. package/package.json +12 -12
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CompositionInspector = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const client_id_1 = require("../../helpers/client-id");
6
7
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
7
8
  const browse_elements_1 = require("../../icons/browse-elements");
8
9
  const frame_1 = require("../../icons/frame");
@@ -123,9 +124,10 @@ const CompositionVisualControlsSection = ({ readOnlyStudio }) => {
123
124
  ] }));
124
125
  };
125
126
  const CompositionInspector = ({ composition, currentDefaultProps, readOnlyStudio, setDefaultProps }) => {
127
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
126
128
  return (jsx_runtime_1.jsxs("div", { style: styles_1.scrollableContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: [
127
129
  jsx_runtime_1.jsxs("div", { style: styles_1.inspectorOverviewSection, children: [
128
- jsx_runtime_1.jsx(CompositionInspectorHeader_1.CompositionInspectorHeader, {}), jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), jsx_runtime_1.jsx(CompositionMetadata_1.CompositionMetadata, { compositionId: composition.id, disabled: readOnlyStudio, stack: composition.stack })
130
+ jsx_runtime_1.jsx(CompositionInspectorHeader_1.CompositionInspectorHeader, {}), jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), jsx_runtime_1.jsx(CompositionMetadata_1.CompositionMetadata, { compositionId: composition.id, disabled: readOnlyStudio || previewServerState.type !== 'connected', stack: composition.stack })
129
131
  ] }), jsx_runtime_1.jsx(CompositionDefaultPropsSection, { composition: composition, currentDefaultProps: currentDefaultProps, readOnlyStudio: readOnlyStudio, setDefaultProps: setDefaultProps }), jsx_runtime_1.jsx(CompositionVisualControlsSection, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(CompositionActions, { readOnlyStudio: readOnlyStudio })
130
132
  ] }));
131
133
  };
@@ -105,6 +105,7 @@ const SequenceExpandedInspector = ({ track, readOnlyStudio }) => {
105
105
  const sourceLocation = (0, SequenceInspectorHeader_1.useSequenceInspectorSourceLocation)(track.sequence);
106
106
  const connectedCompositions = (0, ConnectedCompositionsSection_1.useConnectedCompositions)({ track });
107
107
  const { validatedLocation } = sourceLocation;
108
+ const stackKey = track.sequence.getStack();
108
109
  const sequenceSelection = (0, react_1.useMemo)(() => {
109
110
  if (!track.nodePathInfo) {
110
111
  return null;
@@ -141,7 +142,7 @@ const SequenceExpandedInspector = ({ track, readOnlyStudio }) => {
141
142
  return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Sequence inspector unavailable" });
142
143
  }
143
144
  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 }), jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorDuplicationSection, { track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
145
+ jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }, stackKey !== null && stackKey !== void 0 ? stackKey : track.sequence.id), jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorDuplicationSection, { track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
145
146
  jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), jsx_runtime_1.jsx(ConnectedCompositionsSection_1.ConnectedCompositionsSection, { connectedCompositions: connectedCompositions })
146
147
  ] })) : 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
148
  jsx_runtime_1.jsx(SplitSequenceAction, { selection: sequenceSelection, track: track }), jsx_runtime_1.jsx(SequenceSourceActions, { selection: sequenceSelection, track: track, validatedSource: validatedLocation.source })
@@ -153,7 +154,6 @@ const SequenceSelectionInspector = ({ selection, readOnlyStudio }) => {
153
154
  if (!track) {
154
155
  return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Sequence inspector unavailable" });
155
156
  }
156
- const stackKey = track.sequence.getStack();
157
- return (jsx_runtime_1.jsx(SequenceExpandedInspector, { track: track, readOnlyStudio: readOnlyStudio }, stackKey !== null && stackKey !== void 0 ? stackKey : track.sequence.id));
157
+ return (jsx_runtime_1.jsx(SequenceExpandedInspector, { track: track, readOnlyStudio: readOnlyStudio }));
158
158
  };
159
159
  exports.SequenceSelectionInspector = SequenceSelectionInspector;
@@ -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
  };
@@ -73,9 +73,9 @@ const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered
73
73
  return;
74
74
  }
75
75
  onItemSelected(id);
76
- (0, pointer_session_1.startPointerSession)({
76
+ (0, pointer_session_1.startCapturedPointerSession)({
77
77
  event: e.nativeEvent,
78
- target: e.currentTarget,
78
+ captureTarget: e.currentTarget,
79
79
  onEnd: (reason, evt) => {
80
80
  if ((reason === 'pointerup' || reason === 'buttons-released') &&
81
81
  evt) {
@@ -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
  };
@@ -34,6 +34,6 @@ const ModalContainer = ({ children, onEscape, onOutsideClick, noZIndex, panelSty
34
34
  // Prevent deselection of currently selected items
35
35
  e.stopPropagation();
36
36
  }, []);
37
- return (jsx_runtime_1.jsx("div", { className: "css-reset", style: backgroundOverlay, role: "dialog", "aria-modal": "true", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { disabled: noZIndex, onOutsideClick: onOutsideClick, onEscape: onEscape, stackOnHighest: true, children: jsx_runtime_1.jsx("div", { style: { ...panel, ...panelStyle }, children: children }) }) }));
37
+ return (jsx_runtime_1.jsx("div", { className: "css-reset", style: backgroundOverlay, role: "dialog", "aria-modal": "true", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { disabled: noZIndex, onOutsideClick: onOutsideClick, onEscape: onEscape, children: jsx_runtime_1.jsx("div", { style: { ...panel, ...panelStyle }, children: children }) }) }));
38
38
  };
39
39
  exports.ModalContainer = ModalContainer;
@@ -6,16 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Modals = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = require("react");
9
- const react_dom_1 = __importDefault(require("react-dom"));
10
9
  const client_id_1 = require("../helpers/client-id");
11
10
  const studio_runtime_config_1 = require("../helpers/studio-runtime-config");
12
11
  const modals_1 = require("../state/modals");
13
- const z_index_1 = require("../state/z-index");
14
12
  const AskAiModal_1 = require("./AskAiModal");
15
13
  const ConfirmationDialog_1 = require("./ConfirmationDialog");
16
14
  const EffectPickerModal_1 = require("./EffectPickerModal");
17
15
  const InstallPackage_1 = require("./InstallPackage");
18
- const portals_1 = require("./Menu/portals");
19
16
  const DeleteComposition_1 = require("./NewComposition/DeleteComposition");
20
17
  const DeleteFolder_1 = require("./NewComposition/DeleteFolder");
21
18
  const DuplicateComposition_1 = require("./NewComposition/DuplicateComposition");
@@ -36,7 +33,6 @@ const Modals = ({ readOnlyStudio }) => {
36
33
  var _a;
37
34
  const modalContextType = (0, react_1.useContext)(modals_1.SelectedModalContext);
38
35
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
39
- const { currentZIndex } = (0, z_index_1.useZIndex)();
40
36
  const { previewServerState, subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
41
37
  const canRender = previewServerState.type === 'connected';
42
38
  (0, react_1.useEffect)(() => {
@@ -51,11 +47,8 @@ const Modals = ({ readOnlyStudio }) => {
51
47
  });
52
48
  });
53
49
  }, [setSelectedModal, subscribeToEvent]);
54
- return react_dom_1.default.createPortal(jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && (jsx_runtime_1.jsx(NewComposition_1.NewComposition, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'new-folder' && (jsx_runtime_1.jsx(NewFolder_1.NewFolder, { parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'duplicate-comp' && (jsx_runtime_1.jsx(DuplicateComposition_1.DuplicateComposition, { compositionType: modalContextType.compositionType, compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-comp' && (jsx_runtime_1.jsx(DeleteComposition_1.DeleteComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'rename-comp' && (jsx_runtime_1.jsx(RenameComposition_1.RenameComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-folder' && (jsx_runtime_1.jsx(DeleteFolder_1.DeleteFolder, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'rename-folder' && (jsx_runtime_1.jsx(RenameFolder_1.RenameFolder, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'rename-static-file' && (jsx_runtime_1.jsx(RenameStaticFile_1.RenameStaticFileModal, { relativePath: modalContextType.relativePath })), modalContextType && modalContextType.type === 'input-props-override' && (jsx_runtime_1.jsx(OverrideInputProps_1.OverrideInputPropsModal, {})), modalContextType && modalContextType.type === 'settings' && (jsx_runtime_1.jsx(SettingsModal_1.SettingsModal, { initialTab: modalContextType.initialTab, initialPublicLicenseKey: modalContextType.initialPublicLicenseKey }, `${modalContextType.initialTab}-${modalContextType.initialPublicLicenseKey}`)), modalContextType && modalContextType.type === 'web-render' && (jsx_runtime_1.jsx(WebRenderModal_1.WebRenderModalWithLoader, { ...modalContextType })), modalContextType &&
50
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && (jsx_runtime_1.jsx(NewComposition_1.NewComposition, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack, canvasCapture: modalContextType.canvasCapture })), modalContextType && modalContextType.type === 'new-folder' && (jsx_runtime_1.jsx(NewFolder_1.NewFolder, { parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'duplicate-comp' && (jsx_runtime_1.jsx(DuplicateComposition_1.DuplicateComposition, { compositionType: modalContextType.compositionType, compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-comp' && (jsx_runtime_1.jsx(DeleteComposition_1.DeleteComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'rename-comp' && (jsx_runtime_1.jsx(RenameComposition_1.RenameComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-folder' && (jsx_runtime_1.jsx(DeleteFolder_1.DeleteFolder, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'rename-folder' && (jsx_runtime_1.jsx(RenameFolder_1.RenameFolder, { folderName: modalContextType.folderName, parentName: modalContextType.parentName, stack: modalContextType.stack })), modalContextType && modalContextType.type === 'rename-static-file' && (jsx_runtime_1.jsx(RenameStaticFile_1.RenameStaticFileModal, { relativePath: modalContextType.relativePath })), modalContextType && modalContextType.type === 'input-props-override' && (jsx_runtime_1.jsx(OverrideInputProps_1.OverrideInputPropsModal, {})), modalContextType && modalContextType.type === 'settings' && (jsx_runtime_1.jsx(SettingsModal_1.SettingsModal, { initialTab: modalContextType.initialTab, initialPublicLicenseKey: modalContextType.initialPublicLicenseKey }, `${modalContextType.initialTab}-${modalContextType.initialPublicLicenseKey}`)), modalContextType && modalContextType.type === 'web-render' && (jsx_runtime_1.jsx(WebRenderModal_1.WebRenderModalWithLoader, { ...modalContextType })), modalContextType &&
55
51
  modalContextType.type === 'server-render' &&
56
- (canRender || modalContextType.readOnlyStudio) ? (jsx_runtime_1.jsx(ServerRenderModal_1.RenderModalWithLoader, { readOnlyStudio: (_a = modalContextType.readOnlyStudio) !== null && _a !== void 0 ? _a : false, initialFrame: modalContextType.initialFrame, initialDarkMode: modalContextType.initialDarkMode, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialOffthreadVideoThreads: modalContextType.initialOffthreadVideoThreads, initialMediaCacheSizeInBytes: modalContextType.initialMediaCacheSizeInBytes, initialConcurrency: modalContextType.initialConcurrency, maxConcurrency: modalContextType.maxConcurrency, minConcurrency: modalContextType.minConcurrency, initialStillImageFormat: modalContextType.initialStillImageFormat, initialMuted: modalContextType.initialMuted, initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack, initialProResProfile: modalContextType.initialProResProfile, initialx264Preset: modalContextType.initialx264Preset, initialGopSize: modalContextType.initialGopSize, initialPixelFormat: modalContextType.initialPixelFormat, initialAudioBitrate: modalContextType.initialAudioBitrate, initialVideoBitrate: modalContextType.initialVideoBitrate, initialEveryNthFrame: modalContextType.initialEveryNthFrame, initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops, initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, initialEncodingBufferSize: modalContextType.initialEncodingBufferSize, initialEncodingMaxRate: modalContextType.initialEncodingMaxRate, initialUserAgent: modalContextType.initialUserAgent, initialColorSpace: modalContextType.initialColorSpace, initialMultiProcessOnLinux: modalContextType.initialMultiProcessOnLinux, initialRepro: modalContextType.initialRepro, initialBeep: modalContextType.initialBeep, initialForSeamlessAacConcatenation: modalContextType.initialForSeamlessAacConcatenation, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec, defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec, renderTypeOfLastRender: modalContextType.renderTypeOfLastRender, defaultMetadata: modalContextType.defaulMetadata, initialHardwareAcceleration: modalContextType.initialHardwareAcceleration, initialSampleRate: modalContextType.initialSampleRate, initialChromeMode: modalContextType.initialChromeMode, renderDefaults: modalContextType.renderDefaults })) : null, modalContextType && modalContextType.type === 'render-progress' && (jsx_runtime_1.jsx(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && (jsx_runtime_1.jsx(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'install-packages' && (jsx_runtime_1.jsx(InstallPackage_1.InstallPackageModal, { packageManager: modalContextType.packageManager })), modalContextType && modalContextType.type === 'quick-switcher' && (jsx_runtime_1.jsx(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode, assetSelection: modalContextType.assetSelection, compositionSelection: modalContextType.compositionSelection })), modalContextType && modalContextType.type === 'add-effect' && (jsx_runtime_1.jsx(EffectPickerModal_1.EffectPickerModal, { state: modalContextType })), modalContextType && modalContextType.type === 'confirmation-dialog' && (jsx_runtime_1.jsx(ConfirmationDialog_1.ConfirmationDialog, { state: modalContextType })), modalContextType && modalContextType.type === 'svg-import-dialog' && (jsx_runtime_1.jsx(SvgImportDialog_1.SvgImportDialog, { state: modalContextType })), (0, studio_runtime_config_1.getStudioAskAIEnabled)() && jsx_runtime_1.jsx(AskAiModal_1.AskAiModal, {})] }),
57
- // Modals must be above overlays opened from the editor, such as the
58
- // floating sidebars used in the mobile layout.
59
- (0, portals_1.getPortal)(currentZIndex + 1));
52
+ (canRender || modalContextType.readOnlyStudio) ? (jsx_runtime_1.jsx(ServerRenderModal_1.RenderModalWithLoader, { readOnlyStudio: (_a = modalContextType.readOnlyStudio) !== null && _a !== void 0 ? _a : false, initialFrame: modalContextType.initialFrame, initialDarkMode: modalContextType.initialDarkMode, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialOffthreadVideoThreads: modalContextType.initialOffthreadVideoThreads, initialMediaCacheSizeInBytes: modalContextType.initialMediaCacheSizeInBytes, initialConcurrency: modalContextType.initialConcurrency, maxConcurrency: modalContextType.maxConcurrency, minConcurrency: modalContextType.minConcurrency, initialStillImageFormat: modalContextType.initialStillImageFormat, initialMuted: modalContextType.initialMuted, initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack, initialProResProfile: modalContextType.initialProResProfile, initialx264Preset: modalContextType.initialx264Preset, initialGopSize: modalContextType.initialGopSize, initialPixelFormat: modalContextType.initialPixelFormat, initialAudioBitrate: modalContextType.initialAudioBitrate, initialVideoBitrate: modalContextType.initialVideoBitrate, initialEveryNthFrame: modalContextType.initialEveryNthFrame, initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops, initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, initialEncodingBufferSize: modalContextType.initialEncodingBufferSize, initialEncodingMaxRate: modalContextType.initialEncodingMaxRate, initialUserAgent: modalContextType.initialUserAgent, initialColorSpace: modalContextType.initialColorSpace, initialMultiProcessOnLinux: modalContextType.initialMultiProcessOnLinux, initialRepro: modalContextType.initialRepro, initialBeep: modalContextType.initialBeep, initialForSeamlessAacConcatenation: modalContextType.initialForSeamlessAacConcatenation, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec, defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec, renderTypeOfLastRender: modalContextType.renderTypeOfLastRender, defaultMetadata: modalContextType.defaulMetadata, initialHardwareAcceleration: modalContextType.initialHardwareAcceleration, initialSampleRate: modalContextType.initialSampleRate, initialChromeMode: modalContextType.initialChromeMode, renderDefaults: modalContextType.renderDefaults })) : null, modalContextType && modalContextType.type === 'render-progress' && (jsx_runtime_1.jsx(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && (jsx_runtime_1.jsx(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'install-packages' && (jsx_runtime_1.jsx(InstallPackage_1.InstallPackageModal, { packageManager: modalContextType.packageManager })), modalContextType && modalContextType.type === 'quick-switcher' && (jsx_runtime_1.jsx(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode, assetSelection: modalContextType.assetSelection, compositionSelection: modalContextType.compositionSelection })), modalContextType && modalContextType.type === 'add-effect' && (jsx_runtime_1.jsx(EffectPickerModal_1.EffectPickerModal, { state: modalContextType })), modalContextType && modalContextType.type === 'confirmation-dialog' && (jsx_runtime_1.jsx(ConfirmationDialog_1.ConfirmationDialog, { state: modalContextType })), modalContextType && modalContextType.type === 'svg-import-dialog' && (jsx_runtime_1.jsx(SvgImportDialog_1.SvgImportDialog, { state: modalContextType })), (0, studio_runtime_config_1.getStudioAskAIEnabled)() && jsx_runtime_1.jsx(AskAiModal_1.AskAiModal, {})] }));
60
53
  };
61
54
  exports.Modals = Modals;
@@ -449,9 +449,9 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
449
449
  lastDragValue = nextValue;
450
450
  onValueChange(nextValue);
451
451
  };
452
- (0, pointer_session_1.startPointerSession)({
452
+ (0, pointer_session_1.startCapturedPointerSession)({
453
453
  event: e.nativeEvent,
454
- target,
454
+ captureTarget: target,
455
455
  onMove: moveListener,
456
456
  onEnd: (reason) => {
457
457
  pointerDownRef.current = false;
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
+ import type { CanvasCaptureImport } from '../../state/modals';
2
3
  export declare const NewComposition: React.FC<{
3
4
  readonly folderName: string | null;
4
5
  readonly parentName: string | null;
5
6
  readonly stack: string | null;
7
+ readonly canvasCapture: CanvasCaptureImport | null;
6
8
  }>;
@@ -4,6 +4,9 @@ exports.NewComposition = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
+ const get_static_files_1 = require("../../api/get-static-files");
8
+ const write_static_file_1 = require("../../api/write-static-file");
9
+ const install_required_package_1 = require("../../helpers/install-required-package");
7
10
  const use_create_composition_1 = require("../../helpers/use-create-composition");
8
11
  const layout_1 = require("../layout");
9
12
  const ModalFooter_1 = require("../ModalFooter");
@@ -27,14 +30,15 @@ const content = {
27
30
  const folderPathStyle = {
28
31
  fontSize: 14,
29
32
  };
30
- const NewCompositionLoaded = ({ folderName, parentName, stack }) => {
33
+ const NewCompositionLoaded = ({ canvasCapture, folderName, parentName, stack }) => {
34
+ var _a;
31
35
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
32
36
  const resolvedComposition = remotion_1.Internals.useResolvedVideoConfig(null);
33
37
  const initialComposition = (resolvedComposition === null || resolvedComposition === void 0 ? void 0 : resolvedComposition.type) === 'success' ||
34
38
  (resolvedComposition === null || resolvedComposition === void 0 ? void 0 : resolvedComposition.type) === 'success-and-refreshing'
35
39
  ? resolvedComposition.result
36
40
  : null;
37
- const initialDimensions = (0, get_new_composition_defaults_1.getNewCompositionDefaults)(initialComposition);
41
+ const initialDimensions = (0, get_new_composition_defaults_1.getNewCompositionDefaults)(initialComposition, (_a = canvasCapture === null || canvasCapture === void 0 ? void 0 : canvasCapture.durationInSeconds) !== null && _a !== void 0 ? _a : null);
38
42
  const [newId, setName] = (0, react_1.useState)(() => (0, use_create_composition_1.getUniqueCompositionName)(compositions));
39
43
  const inputRef = (0, react_1.useRef)(null);
40
44
  (0, react_1.useEffect)(() => {
@@ -98,13 +102,41 @@ const NewCompositionLoaded = ({ folderName, parentName, stack }) => {
98
102
  parentName,
99
103
  selectedFrameRate,
100
104
  size,
105
+ canvasCapture: canvasCapture === null
106
+ ? null
107
+ : {
108
+ data: canvasCapture.data,
109
+ videoFileName: canvasCapture.file.name,
110
+ videoHeight: canvasCapture.height,
111
+ videoWidth: canvasCapture.width,
112
+ },
101
113
  });
114
+ const createCanvasCaptureComposition = (0, react_1.useCallback)(async ({ signal, symbolicatedStack, }) => {
115
+ if (canvasCapture !== null) {
116
+ const existingFile = (0, get_static_files_1.getStaticFiles)().find((file) => file.name === canvasCapture.file.name);
117
+ if (existingFile !== undefined &&
118
+ existingFile.sizeInBytes !== canvasCapture.file.size) {
119
+ throw new Error(`File with name ${canvasCapture.file.name} already exists and is different`);
120
+ }
121
+ await (0, install_required_package_1.installRequiredPackages)([
122
+ { name: '@remotion/media', version: null },
123
+ { name: '@remotion/mac-cursors', version: null },
124
+ ]);
125
+ if (existingFile === undefined) {
126
+ await (0, write_static_file_1.writeStaticFile)({
127
+ contents: await canvasCapture.file.arrayBuffer(),
128
+ filePath: canvasCapture.file.name,
129
+ });
130
+ }
131
+ }
132
+ return createComposition({ signal, symbolicatedStack });
133
+ }, [canvasCapture, createComposition]);
102
134
  const onSubmit = (0, react_1.useCallback)((e) => {
103
135
  e.preventDefault();
104
136
  }, []);
105
137
  const folderPath = [parentName, folderName].filter(Boolean).join('/');
106
138
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
107
- jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: "New composition" }), jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [
139
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: canvasCapture === null ? 'New composition' : 'Import Canvas Capture' }), jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [
108
140
  jsx_runtime_1.jsxs("div", { style: content, children: [folderPath ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
109
141
  jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Folder" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx("span", { style: folderPathStyle, children: folderPath }) })
110
142
  ] })) : null, jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
@@ -125,14 +157,14 @@ const NewCompositionLoaded = ({ folderName, parentName, stack }) => {
125
157
  ] }), jsx_runtime_1.jsx(NewCompDuration_1.NewCompDuration, { durationInFrames: durationInFrames, setDurationInFrames: setDurationInFrames }), jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
126
158
  jsx_runtime_1.jsx("div", { style: layout_2.label, children: "FPS" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: selectedFrameRate, onTextChange: onTextFpsChange, placeholder: "Frame rate (fps)", name: "fps", min: 1, required: true, status: "ok", max: 240, step: 0.01, onValueChange: onFpsChange, rightAlign: false }) })
127
159
  ] })
128
- ] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: null, errorNotification: "Could not create composition", successNotification: `Created ${newId}`, genericSubmitLabel: "Add to root file", submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, stack: stack, valid: valid, onSuccess: null, applyCodemod: ({ signal, symbolicatedStack }) => createComposition({
160
+ ] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsx(CodemodFooter_1.CodemodFooter, { loadingNotification: null, errorNotification: "Could not create composition", successNotification: `Created ${newId}`, genericSubmitLabel: "Add to root file", submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`, codemod: codemod, stack: stack, valid: valid, onSuccess: null, applyCodemod: ({ signal, symbolicatedStack }) => createCanvasCaptureComposition({
129
161
  signal,
130
162
  symbolicatedStack,
131
163
  }), fallbackToRootFile: true }) })
132
164
  ] })
133
165
  ] }));
134
166
  };
135
- const NewComposition = ({ folderName, parentName, stack }) => {
136
- return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { children: jsx_runtime_1.jsx(NewCompositionLoaded, { folderName: folderName, parentName: parentName, stack: stack }) }));
167
+ const NewComposition = ({ canvasCapture, folderName, parentName, stack }) => {
168
+ return (jsx_runtime_1.jsx(DismissableModal_1.DismissableModal, { children: jsx_runtime_1.jsx(NewCompositionLoaded, { canvasCapture: canvasCapture, folderName: folderName, parentName: parentName, stack: stack }) }));
137
169
  };
138
170
  exports.NewComposition = NewComposition;
@@ -1,4 +1,4 @@
1
1
  import type { VideoConfig } from 'remotion';
2
2
  type CompositionDimensions = Pick<VideoConfig, 'width' | 'height' | 'fps' | 'durationInFrames'>;
3
- export declare const getNewCompositionDefaults: (composition: CompositionDimensions | null) => CompositionDimensions;
3
+ export declare const getNewCompositionDefaults: (composition: CompositionDimensions | null, canvasCaptureDurationInSeconds: number | null) => CompositionDimensions;
4
4
  export {};
@@ -7,7 +7,15 @@ const defaultCompositionDimensions = {
7
7
  fps: 30,
8
8
  durationInFrames: 150,
9
9
  };
10
- const getNewCompositionDefaults = (composition) => {
10
+ const canvasCaptureFps = 60;
11
+ const getNewCompositionDefaults = (composition, canvasCaptureDurationInSeconds) => {
12
+ if (canvasCaptureDurationInSeconds !== null) {
13
+ return {
14
+ ...defaultCompositionDimensions,
15
+ fps: canvasCaptureFps,
16
+ durationInFrames: Math.max(1, Math.ceil(canvasCaptureDurationInSeconds * canvasCaptureFps)),
17
+ };
18
+ }
11
19
  return composition !== null && composition !== void 0 ? composition : defaultCompositionDimensions;
12
20
  };
13
21
  exports.getNewCompositionDefaults = getNewCompositionDefaults;
@@ -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);
@@ -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) {
@@ -29,12 +29,29 @@ const right = {
29
29
  const BundlingProgress = ({ progress, doneIn }) => {
30
30
  return (jsx_runtime_1.jsxs("div", { style: progressItem, children: [progress === 1 ? (jsx_runtime_1.jsx(SuccessIcon_1.SuccessIcon, {})) : (jsx_runtime_1.jsx(CircularProgress_1.CircularProgress, { progress: progress })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: progress === 1 ? 'Bundled' : `Bundling ${progress * 100}%` }), doneIn ? jsx_runtime_1.jsxs("div", { style: right, children: [doneIn, "ms"] }) : null] }));
31
31
  };
32
- const BrowserSetupProgress = ({ progress, doneIn, startedBundling, alreadyAvailable }) => {
33
- return (jsx_runtime_1.jsxs("div", { style: progressItem, children: [progress === 1 || alreadyAvailable ? (jsx_runtime_1.jsx(SuccessIcon_1.SuccessIcon, {})) : (jsx_runtime_1.jsx(CircularProgress_1.CircularProgress, { progress: progress })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: alreadyAvailable && startedBundling
34
- ? 'Headless browser already available'
35
- : progress === 1
36
- ? 'Downloaded Headless Shell'
37
- : `Downloading Headless Shell ${Math.round(progress * 100)}%` }), doneIn ? jsx_runtime_1.jsxs("div", { style: right, children: [doneIn, "ms"] }) : null] }));
32
+ const failIconStyle = {
33
+ width: 16,
34
+ height: 16,
35
+ };
36
+ const FailIcon = () => {
37
+ return (jsx_runtime_1.jsx("svg", { style: failIconStyle, viewBox: "0 0 512 512", children: jsx_runtime_1.jsx("path", { fill: colors_1.FAIL_COLOR, d: "M0 160V352L160 512H352L512 352V160L352 0H160L0 160zm353.9 32l-17 17-47 47 47 47 17 17L320 353.9l-17-17-47-47-47 47-17 17L158.1 320l17-17 47-47-47-47-17-17L192 158.1l17 17 47 47 47-47 17-17L353.9 192z" }) }));
38
+ };
39
+ const BrowserSetupProgress = ({ progress, doneIn, startedBundling, alreadyAvailable, error }) => {
40
+ if (error) {
41
+ return (jsx_runtime_1.jsxs("div", { style: progressItem, children: [
42
+ jsx_runtime_1.jsx(FailIcon, {}), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: "Failed to download Headless Shell" })
43
+ ] }));
44
+ }
45
+ // Before the first download callback or the bundling phase, we don't know
46
+ // yet whether the browser is available - don't show a success state.
47
+ const stillChecking = alreadyAvailable && progress === 0 && !startedBundling;
48
+ return (jsx_runtime_1.jsxs("div", { style: progressItem, children: [stillChecking ? (jsx_runtime_1.jsx(CircularProgress_1.CircularProgress, { progress: 0 })) : progress === 1 || alreadyAvailable ? (jsx_runtime_1.jsx(SuccessIcon_1.SuccessIcon, {})) : (jsx_runtime_1.jsx(CircularProgress_1.CircularProgress, { progress: progress })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: stillChecking
49
+ ? 'Checking for Headless Shell'
50
+ : alreadyAvailable && startedBundling
51
+ ? 'Headless browser already available'
52
+ : progress === 1
53
+ ? 'Downloaded Headless Shell'
54
+ : `Downloading Headless Shell ${Math.round(progress * 100)}%` }), doneIn ? jsx_runtime_1.jsxs("div", { style: right, children: [doneIn, "ms"] }) : null] }));
38
55
  };
39
56
  const RenderingProgress = ({ progress }) => {
40
57
  return (jsx_runtime_1.jsxs("div", { style: progressItem, children: [progress.frames === progress.totalFrames ? (jsx_runtime_1.jsx(SuccessIcon_1.SuccessIcon, {})) : (jsx_runtime_1.jsx(CircularProgress_1.CircularProgress, { progress: progress.frames / progress.totalFrames })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: progress.doneIn
@@ -2,4 +2,5 @@ import React from 'react';
2
2
  export declare const InfoBubble: React.FC<{
3
3
  readonly title: string;
4
4
  readonly children: React.ReactNode;
5
+ readonly horizontalAlignment?: 'left' | 'right';
5
6
  }>;