@remotion/studio 4.0.507 → 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 (130) hide show
  1. package/dist/FastRefreshProvider.js +13 -9
  2. package/dist/components/CodingAgentIcon.d.ts +3 -1
  3. package/dist/components/CodingAgentIcon.js +4 -9
  4. package/dist/components/ConfigureDefaultEditorModal.js +1 -1
  5. package/dist/components/ContextMenu.d.ts +1 -0
  6. package/dist/components/ContextMenu.js +32 -5
  7. package/dist/components/EditorContent.js +4 -3
  8. package/dist/components/InlineAction.d.ts +2 -1
  9. package/dist/components/InlineAction.js +3 -3
  10. package/dist/components/InspectorLocationCopy.js +1 -1
  11. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  12. package/dist/components/InspectorOpenInEditor.js +44 -3
  13. package/dist/components/InspectorPanel/AlignmentControls.js +2 -2
  14. package/dist/components/InspectorPanel/CompositionInspector.js +3 -1
  15. package/dist/components/InspectorPanel/styles.js +1 -1
  16. package/dist/components/InspectorSequenceSection.js +36 -4
  17. package/dist/components/MenuBuildIndicator.js +1 -1
  18. package/dist/components/PlayPause.d.ts +1 -1
  19. package/dist/components/PlayPause.js +61 -12
  20. package/dist/components/RenderButton.js +16 -12
  21. package/dist/components/RenderModal/GuiRenderStatus.js +23 -6
  22. package/dist/components/RenderModal/InfoBubble.d.ts +1 -0
  23. package/dist/components/RenderModal/InfoBubble.js +6 -4
  24. package/dist/components/RenderModal/InfoTooltip.d.ts +1 -0
  25. package/dist/components/RenderModal/InfoTooltip.js +12 -12
  26. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.d.ts +5 -0
  27. package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +16 -3
  28. package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.js +1 -1
  29. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.d.ts +2 -0
  30. package/dist/components/RenderModal/SchemaEditor/ZodBooleanEditor.js +3 -2
  31. package/dist/components/RenderModal/SchemaEditor/ZodColorEditor.js +1 -1
  32. package/dist/components/RenderModal/SchemaEditor/ZodDateEditor.js +1 -1
  33. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +2 -1
  34. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +1 -1
  35. package/dist/components/RenderModal/SchemaEditor/ZodMatrixEditor.js +1 -1
  36. package/dist/components/RenderModal/SchemaEditor/ZodNonEditableValue.js +1 -1
  37. package/dist/components/RenderModal/SchemaEditor/ZodNumberEditor.js +1 -1
  38. package/dist/components/RenderModal/SchemaEditor/ZodObjectEditor.js +1 -1
  39. package/dist/components/RenderModal/SchemaEditor/ZodOrNullishEditor.js +6 -1
  40. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +1 -1
  41. package/dist/components/RenderModal/SchemaEditor/ZodStringEditor.js +1 -1
  42. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +1 -1
  43. package/dist/components/RenderModal/SchemaEditor/ZodTextareaEditor.js +1 -1
  44. package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.js +1 -1
  45. package/dist/components/RenderModal/SchemaEditor/zod-schema-type.d.ts +1 -0
  46. package/dist/components/RenderModal/SchemaEditor/zod-schema-type.js +12 -1
  47. package/dist/components/SelectedOutlineCanvasRotation.d.ts +9 -0
  48. package/dist/components/SelectedOutlineCanvasRotation.js +237 -0
  49. package/dist/components/SelectedOutlineElement.d.ts +2 -1
  50. package/dist/components/SelectedOutlineElement.js +36 -5
  51. package/dist/components/SelectedOutlineOverlay.d.ts +1 -1
  52. package/dist/components/SelectedOutlineOverlay.js +55 -26
  53. package/dist/components/SelectedOutlinePolygon.d.ts +1 -0
  54. package/dist/components/SelectedOutlinePolygon.js +4 -3
  55. package/dist/components/SelectedOutlineRenderer.d.ts +1 -0
  56. package/dist/components/SelectedOutlineRenderer.js +24 -7
  57. package/dist/components/SelectedOutlineRotationCornerHandle.d.ts +1 -0
  58. package/dist/components/SelectedOutlineRotationCornerHandle.js +7 -5
  59. package/dist/components/SelectedOutlineScaleEdgeLine.d.ts +1 -0
  60. package/dist/components/SelectedOutlineScaleEdgeLine.js +9 -5
  61. package/dist/components/SelectedOutlineTransformOriginHandle.js +48 -22
  62. package/dist/components/SequencePropsSubscriptionProvider.js +8 -0
  63. package/dist/components/SettingsModalFooter.js +1 -1
  64. package/dist/components/Timeline/SequencePropsObserver.js +97 -1
  65. package/dist/components/Timeline/SubscribeToNodePaths.js +4 -2
  66. package/dist/components/Timeline/TimelineEffectItem.js +1 -4
  67. package/dist/components/Timeline/TimelineFieldRowContent.js +10 -3
  68. package/dist/components/Timeline/TimelineRotationField.js +84 -12
  69. package/dist/components/Timeline/TimelineScaleField.js +58 -4
  70. package/dist/components/Timeline/TimelineSelection.d.ts +4 -0
  71. package/dist/components/Timeline/TimelineSelection.js +45 -2
  72. package/dist/components/Timeline/TimelineSequenceItem.js +42 -1
  73. package/dist/components/Timeline/TimelineSequencePropItem.js +5 -2
  74. package/dist/components/Timeline/TimelineTransformOriginField.js +78 -4
  75. package/dist/components/Timeline/TimelineTranslateField.js +55 -15
  76. package/dist/components/Timeline/Transform3DModeContext.d.ts +1 -0
  77. package/dist/components/Timeline/Transform3DModeContext.js +5 -0
  78. package/dist/components/Timeline/delete-selected-timeline-item.js +0 -6
  79. package/dist/components/Timeline/get-sequence-context-menu-items.js +13 -6
  80. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
  81. package/dist/components/Timeline/sequence-props-subscription-store.js +5 -2
  82. package/dist/components/Timeline/timeline-field-display-utils.js +2 -2
  83. package/dist/components/Timeline/timeline-field-row-layout.d.ts +6 -0
  84. package/dist/components/Timeline/timeline-field-row-layout.js +16 -1
  85. package/dist/components/Timeline/timeline-rotation-utils.d.ts +16 -0
  86. package/dist/components/Timeline/timeline-rotation-utils.js +145 -4
  87. package/dist/components/Timeline/timeline-translate-utils.d.ts +3 -2
  88. package/dist/components/Timeline/timeline-translate-utils.js +8 -4
  89. package/dist/components/Timeline/transform-3d-mode.d.ts +6 -0
  90. package/dist/components/Timeline/transform-3d-mode.js +36 -0
  91. package/dist/components/Timeline/transform-origin-utils.d.ts +4 -0
  92. package/dist/components/Timeline/transform-origin-utils.js +12 -6
  93. package/dist/components/Timeline/use-open-sequence-in-apps.js +1 -1
  94. package/dist/components/Timeline/use-resolved-stack-react-to-change.d.ts +5 -1
  95. package/dist/components/Timeline/use-resolved-stack-react-to-change.js +45 -9
  96. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -1
  97. package/dist/components/Timeline/use-sequence-props-subscription.js +7 -2
  98. package/dist/components/call-api.js +2 -0
  99. package/dist/components/canvas-rotation-cursor.d.ts +1 -0
  100. package/dist/components/canvas-rotation-cursor.js +14 -0
  101. package/dist/components/get-open-in-menu-items.d.ts +6 -1
  102. package/dist/components/get-open-in-menu-items.js +69 -8
  103. package/dist/components/selected-outline-drag.d.ts +11 -5
  104. package/dist/components/selected-outline-drag.js +80 -42
  105. package/dist/components/selected-outline-measurement.d.ts +5 -0
  106. package/dist/components/selected-outline-measurement.js +28 -1
  107. package/dist/components/selected-outline-types.d.ts +6 -0
  108. package/dist/esm/{chunk-ptnd65a9.js → chunk-zpn4m49r.js} +8458 -6911
  109. package/dist/esm/index.mjs +357 -2
  110. package/dist/esm/internals.mjs +8458 -6911
  111. package/dist/esm/previewEntry.mjs +8363 -6816
  112. package/dist/esm/renderEntry.mjs +1 -1
  113. package/dist/helpers/get-box-quads-polyfill-internals.js +10 -2
  114. package/dist/helpers/open-in-editor.d.ts +3 -1
  115. package/dist/helpers/open-in-editor.js +5 -1
  116. package/dist/helpers/preview-server-events.js +4 -0
  117. package/dist/helpers/sequence-node-path-mutations.d.ts +4 -0
  118. package/dist/helpers/sequence-node-path-mutations.js +31 -0
  119. package/dist/icons/cube.d.ts +4 -0
  120. package/dist/icons/cube.js +6 -0
  121. package/dist/icons/finder.d.ts +4 -0
  122. package/dist/icons/finder.js +8 -0
  123. package/dist/icons/terminal.d.ts +6 -0
  124. package/dist/icons/terminal.js +46 -0
  125. package/dist/index.d.ts +15 -0
  126. package/dist/index.js +8 -0
  127. package/dist/state/transform-3d-mode.d.ts +10 -0
  128. package/dist/state/transform-3d-mode.js +27 -0
  129. package/dist/state/z-index.js +5 -8
  130. package/package.json +12 -12
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FastRefreshProvider = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const studio_shared_1 = require("@remotion/studio-shared");
5
6
  const react_1 = require("react");
7
+ const react_dom_1 = require("react-dom");
6
8
  const fast_refresh_context_1 = require("./fast-refresh-context");
7
9
  const FastRefreshProvider = ({ children }) => {
8
10
  const [fastRefreshes, setFastRefreshes] = (0, react_1.useState)(0);
@@ -11,15 +13,17 @@ const FastRefreshProvider = ({ children }) => {
11
13
  setManualRefreshes((i) => i + 1);
12
14
  }, []);
13
15
  (0, react_1.useEffect)(() => {
14
- if (typeof __webpack_module__ !== 'undefined') {
15
- if (__webpack_module__.hot) {
16
- __webpack_module__.hot.addStatusHandler((status) => {
17
- if (status === 'idle') {
18
- setFastRefreshes((i) => i + 1);
19
- }
20
- });
21
- }
22
- }
16
+ const onReactRefreshFinished = () => {
17
+ // Commit consumers and their layout effects before the browser paints
18
+ // the refreshed composition with stale node-path statuses.
19
+ (0, react_dom_1.flushSync)(() => {
20
+ setFastRefreshes((i) => i + 1);
21
+ });
22
+ };
23
+ window.addEventListener(studio_shared_1.REACT_REFRESH_FINISHED_EVENT, onReactRefreshFinished);
24
+ return () => {
25
+ window.removeEventListener(studio_shared_1.REACT_REFRESH_FINISHED_EVENT, onReactRefreshFinished);
26
+ };
23
27
  }, []);
24
28
  const value = (0, react_1.useMemo)(() => ({ fastRefreshes, manualRefreshes, increaseManualRefreshes }), [fastRefreshes, manualRefreshes, increaseManualRefreshes]);
25
29
  return (jsx_runtime_1.jsx(fast_refresh_context_1.FastRefreshContext.Provider, { value: value, children: children }));
@@ -1,4 +1,6 @@
1
+ import type { DefaultCodingAgent } from '@remotion/renderer';
1
2
  import React from 'react';
2
3
  export declare const CodingAgentIcon: React.FC<{
3
- readonly iconDataUrl: string | null;
4
+ readonly codingAgentId: DefaultCodingAgent | null;
5
+ readonly size: number;
4
6
  }>;
@@ -3,15 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CodingAgentIcon = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const apps_1 = require("../icons/apps");
6
- const iconStyle = {
7
- flexShrink: 0,
8
- height: 18,
9
- width: 18,
10
- };
11
- const CodingAgentIcon = ({ iconDataUrl }) => {
12
- if (iconDataUrl === null) {
13
- return jsx_runtime_1.jsx(apps_1.AppsIcon, { height: 18, width: 18 });
6
+ const CodingAgentIcon = ({ codingAgentId, size }) => {
7
+ if (codingAgentId === null) {
8
+ return jsx_runtime_1.jsx(apps_1.AppsIcon, { height: size, width: size });
14
9
  }
15
- return (jsx_runtime_1.jsx("img", { alt: "", "aria-hidden": true, draggable: false, src: iconDataUrl, style: iconStyle }));
10
+ return (jsx_runtime_1.jsx("img", { alt: "", "aria-hidden": true, "data-coding-agent-icon": codingAgentId, draggable: false, src: `/api/app-icon/coding-agent/${codingAgentId}.png`, style: { flexShrink: 0, height: size, width: size } }));
16
11
  };
17
12
  exports.CodingAgentIcon = CodingAgentIcon;
@@ -125,7 +125,7 @@ const DefaultEditorSettings = () => {
125
125
  id: codingAgent.id,
126
126
  keyHint: null,
127
127
  label: (jsx_runtime_1.jsxs("span", { style: appLabel, children: [
128
- jsx_runtime_1.jsx(CodingAgentIcon_1.CodingAgentIcon, { iconDataUrl: codingAgent.iconDataUrl }), jsx_runtime_1.jsx("span", { style: appName, children: codingAgent.name })
128
+ jsx_runtime_1.jsx(CodingAgentIcon_1.CodingAgentIcon, { codingAgentId: codingAgent.id, size: 18 }), jsx_runtime_1.jsx("span", { style: appName, children: codingAgent.name })
129
129
  ] })),
130
130
  leftItem: selectedCodingAgent === codingAgent.id ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
131
131
  onClick: () => {
@@ -14,5 +14,6 @@ export declare const ContextMenu: React.ForwardRefExoticComponent<ContextMenuPro
14
14
  export declare const ContextMenuForTarget: React.FC<{
15
15
  readonly triggerRef: React.RefObject<HTMLElement | SVGElement | null>;
16
16
  readonly getItems: ContextMenuItemsFactory;
17
+ readonly onOpenChange?: (open: boolean) => void;
17
18
  }>;
18
19
  export {};
@@ -236,15 +236,26 @@ exports.ContextMenu = react_1.default.forwardRef(({ children, getItems, style =
236
236
  jsx_runtime_1.jsx("div", { ref: setRef, onContextMenu: () => false, style: style, className: className, onPointerDown: onPointerDown, children: children }), opened.type === 'open' ? (jsx_runtime_1.jsx(ContextMenuPortal, { menuTreeId: menuTreeIdRef.current, sizeSource: ref, currentZIndex: currentZIndex, onHide: onHide, opened: opened })) : null] }));
237
237
  });
238
238
  exports.ContextMenu.displayName = 'ContextMenu';
239
- const ContextMenuForTarget = ({ triggerRef, getItems }) => {
239
+ const ContextMenuForTarget = ({ triggerRef, getItems, onOpenChange = undefined }) => {
240
240
  const idRef = (0, react_1.useRef)(nextContextMenuId++);
241
241
  const menuTreeIdRef = (0, react_1.useRef)((0, menu_tree_context_1.getNextMenuTreeId)());
242
242
  const invocationRef = (0, react_1.useRef)(0);
243
+ const isOpenRef = (0, react_1.useRef)(false);
243
244
  const getItemsRef = (0, react_1.useRef)(getItems);
245
+ const onOpenChangeRef = (0, react_1.useRef)(onOpenChange);
244
246
  getItemsRef.current = getItems;
247
+ onOpenChangeRef.current = onOpenChange;
245
248
  const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
246
249
  const [body, setBody] = (0, react_1.useState)(null);
247
250
  const { currentZIndex } = (0, z_index_1.useZIndex)();
251
+ const setOpenLifecycleState = (0, react_1.useCallback)((open) => {
252
+ var _a;
253
+ if (isOpenRef.current === open) {
254
+ return;
255
+ }
256
+ isOpenRef.current = open;
257
+ (_a = onOpenChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onOpenChangeRef, open);
258
+ }, []);
248
259
  (0, react_1.useEffect)(() => {
249
260
  // Access document.body after mount so importing this component stays safe
250
261
  // in DOM-less test environments.
@@ -260,8 +271,21 @@ const ContextMenuForTarget = ({ triggerRef, getItems }) => {
260
271
  e.preventDefault();
261
272
  e.stopPropagation();
262
273
  const currentInvocation = ++invocationRef.current;
263
- const values = await (0, exports.resolveContextMenuItems)(getItemsRef.current, e);
274
+ setOpenLifecycleState(true);
275
+ let values;
276
+ try {
277
+ values = await (0, exports.resolveContextMenuItems)(getItemsRef.current, e);
278
+ }
279
+ catch (err) {
280
+ if (currentInvocation === invocationRef.current) {
281
+ setOpenLifecycleState(false);
282
+ }
283
+ throw err;
284
+ }
264
285
  if (currentInvocation !== invocationRef.current || values === null) {
286
+ if (currentInvocation === invocationRef.current) {
287
+ setOpenLifecycleState(false);
288
+ }
265
289
  return false;
266
290
  }
267
291
  notifyContextMenuOpened(idRef.current);
@@ -277,16 +301,19 @@ const ContextMenuForTarget = ({ triggerRef, getItems }) => {
277
301
  return () => {
278
302
  current.removeEventListener('contextmenu', onClick);
279
303
  };
280
- }, [triggerRef]);
304
+ }, [setOpenLifecycleState, triggerRef]);
281
305
  (0, react_1.useEffect)(() => {
282
306
  const invocation = invocationRef;
283
307
  return () => {
284
308
  invocation.current++;
309
+ setOpenLifecycleState(false);
285
310
  };
286
- }, []);
311
+ }, [setOpenLifecycleState]);
287
312
  const onHide = (0, react_1.useCallback)(() => {
313
+ invocationRef.current++;
314
+ setOpenLifecycleState(false);
288
315
  setOpened({ type: 'not-open' });
289
- }, []);
316
+ }, [setOpenLifecycleState]);
290
317
  (0, react_1.useEffect)(() => {
291
318
  const onOtherContextMenuOpened = (event) => {
292
319
  if (event.detail === idRef.current) {
@@ -4,6 +4,7 @@ exports.EditorContent = 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 transform_3d_mode_1 = require("../state/transform-3d-mode");
7
8
  const GlobalKeybindings_1 = require("./GlobalKeybindings");
8
9
  const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
9
10
  const MenuToolbar_1 = require("./MenuToolbar");
@@ -38,8 +39,8 @@ const EditorContent = ({ readOnlyStudio, children }) => {
38
39
  const content = (jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, maxFlexerSize: null, minFlexerSize: null, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
39
40
  jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "flexer", children: children }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { allowToCollapse: "none", onCollapse: noop }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { sticky: null, type: "anti-flexer", children: showTimeline ? jsx_runtime_1.jsx(Timeline_1.Timeline, {}) : jsx_runtime_1.jsx(TimelineEmptyState_1.TimelineEmptyState, {}) })
40
41
  ] }));
41
- return (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionProvider, { children: jsx_runtime_1.jsxs(StudioClearSelectionArea, { children: [
42
- jsx_runtime_1.jsx(InitialCompositionLoader_1.InitialCompositionLoader, {}), jsx_runtime_1.jsx(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(GlobalKeybindings_1.GlobalKeybindings, {}), jsx_runtime_1.jsx(TimelineKeyframeDragState_1.TimelineKeyframeDragStateProvider, { children: content })
43
- ] }) }));
42
+ return (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionProvider, { children: jsx_runtime_1.jsx(transform_3d_mode_1.Transform3DModeStateProvider, { children: jsx_runtime_1.jsxs(StudioClearSelectionArea, { children: [
43
+ jsx_runtime_1.jsx(InitialCompositionLoader_1.InitialCompositionLoader, {}), jsx_runtime_1.jsx(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(GlobalKeybindings_1.GlobalKeybindings, {}), jsx_runtime_1.jsx(TimelineKeyframeDragState_1.TimelineKeyframeDragStateProvider, { children: content })
44
+ ] }) }) }));
44
45
  };
45
46
  exports.EditorContent = EditorContent;
@@ -3,8 +3,9 @@ export type RenderInlineAction = (color: string) => React.ReactNode;
3
3
  export type InlineActionProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onClick' | 'style'> & {
4
4
  readonly onClick: React.MouseEventHandler<HTMLButtonElement>;
5
5
  readonly renderAction: RenderInlineAction;
6
+ readonly hoveredColor?: string;
6
7
  readonly unhoveredColor?: string;
7
8
  readonly variant: 'compact' | null;
8
9
  readonly style?: React.CSSProperties;
9
10
  };
10
- export declare const InlineAction: ({ renderAction, onClick, disabled, title, unhoveredColor, variant, style: customStyle, className, ...buttonProps }: InlineActionProps) => import("react/jsx-runtime").JSX.Element;
11
+ export declare const InlineAction: ({ renderAction, onClick, disabled, title, hoveredColor, unhoveredColor, variant, style: customStyle, className, ...buttonProps }: InlineActionProps) => import("react/jsx-runtime").JSX.Element;
@@ -6,7 +6,7 @@ const react_1 = require("react");
6
6
  const colors_1 = require("../helpers/colors");
7
7
  const hoverable_1 = require("../helpers/hoverable");
8
8
  const z_index_1 = require("../state/z-index");
9
- const InlineAction = ({ renderAction, onClick, disabled, title, unhoveredColor = colors_1.LIGHT_TEXT, variant, style: customStyle, className, ...buttonProps }) => {
9
+ const InlineAction = ({ renderAction, onClick, disabled, title, hoveredColor = colors_1.WHITE, unhoveredColor = colors_1.LIGHT_TEXT, variant, style: customStyle, className, ...buttonProps }) => {
10
10
  var _a;
11
11
  const { tabIndex } = (0, z_index_1.useZIndex)();
12
12
  const style = (0, react_1.useMemo)(() => {
@@ -27,11 +27,11 @@ const InlineAction = ({ renderAction, onClick, disabled, title, unhoveredColor =
27
27
  ? colors_1.TRANSPARENT
28
28
  : (0, colors_1.getBackgroundFromHoverState)({ hovered: true, selected: false }),
29
29
  idleColor: unhoveredColor,
30
- hoverColor: disabled ? unhoveredColor : colors_1.WHITE,
30
+ hoverColor: disabled ? unhoveredColor : hoveredColor,
31
31
  }),
32
32
  ...customStyle,
33
33
  };
34
- }, [customStyle, disabled, unhoveredColor, variant]);
34
+ }, [customStyle, disabled, hoveredColor, unhoveredColor, variant]);
35
35
  return (jsx_runtime_1.jsx("button", { ...buttonProps, type: "button", className: className
36
36
  ? `${hoverable_1.HOVERABLE_CLASS_NAME} ${className}`
37
37
  : hoverable_1.HOVERABLE_CLASS_NAME, disabled: disabled, onClick: onClick, style: style, tabIndex: tabIndex, title: title, "aria-label": (_a = buttonProps['aria-label']) !== null && _a !== void 0 ? _a : title, children: renderAction(colors_1.CURRENT_COLOR) }));
@@ -64,6 +64,6 @@ const InspectorLocationCopy = ({ children, location, name, openInEditorLocation
64
64
  opacity: showAction ? 1 : 0,
65
65
  pointerEvents: showAction ? 'auto' : 'none',
66
66
  }, children: [
67
- jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { contextForAgents: contextForAgents, location: openInEditorLocation }), contextForAgents ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopy, renderAction: renderCopyAction, title: "Copy context for agents" })) : null] })) : null] }));
67
+ jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { locationType: null, contextForAgents: contextForAgents, location: openInEditorLocation }), contextForAgents ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopy, renderAction: renderCopyAction, title: "Copy context for agents" })) : null] })) : null] }));
68
68
  };
69
69
  exports.InspectorLocationCopy = InspectorLocationCopy;
@@ -4,4 +4,5 @@ export declare const InspectorOpenInEditor: React.FC<{
4
4
  readonly contextForAgents?: string | null;
5
5
  readonly location: OriginalPosition | null;
6
6
  readonly label?: React.ReactNode;
7
+ readonly locationType: 'file' | 'folder' | null;
7
8
  }>;
@@ -13,6 +13,7 @@ const z_index_1 = require("../state/z-index");
13
13
  const get_open_in_menu_items_1 = require("./get-open-in-menu-items");
14
14
  const InlineDropdown_1 = require("./InlineDropdown");
15
15
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
16
+ const actions_1 = require("./RenderQueue/actions");
16
17
  const use_default_editor_info_1 = require("./use-default-editor-info");
17
18
  const splitButton = {
18
19
  alignItems: 'center',
@@ -40,13 +41,14 @@ const mainButtonBase = {
40
41
  whiteSpace: 'nowrap',
41
42
  };
42
43
  const editorButtonIconSize = 18;
43
- const InspectorOpenInEditor = ({ contextForAgents = null, label, location }) => {
44
+ const InspectorOpenInEditor = ({ contextForAgents = null, label, location, locationType }) => {
44
45
  var _a;
45
46
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
46
47
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
47
48
  const { tabIndex } = (0, z_index_1.useZIndex)();
48
49
  const [hovered, setHovered] = (0, react_1.useState)(false);
49
50
  const [dropdownOpened, setDropdownOpened] = (0, react_1.useState)(false);
51
+ const ignorePointerEnter = (0, react_1.useRef)(false);
50
52
  const editorPickerAvailable = (0, use_default_editor_info_1.canUseEditorPicker)(previewServerState.type === 'connected');
51
53
  const editorInfo = (0, use_default_editor_info_1.useDefaultEditorInfo)(editorPickerAvailable);
52
54
  const codingAgentInfo = (0, use_default_editor_info_1.useDefaultCodingAgentInfo)(editorPickerAvailable);
@@ -79,6 +81,13 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location }) =>
79
81
  event.stopPropagation();
80
82
  openWithEditor(null).catch(() => undefined);
81
83
  }, [openWithEditor]);
84
+ const onDropdownOpenChange = (0, react_1.useCallback)((open) => {
85
+ setDropdownOpened(open);
86
+ if (!open) {
87
+ ignorePointerEnter.current = true;
88
+ setHovered(false);
89
+ }
90
+ }, []);
82
91
  const mainHovered = hovered && !dropdownOpened;
83
92
  const mainButtonStyle = (0, react_1.useMemo)(() => {
84
93
  return {
@@ -113,6 +122,8 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location }) =>
113
122
  editorInfo,
114
123
  excludeCodingAgentId: null,
115
124
  excludeEditorId: preferredEditorId,
125
+ fileManagerDisabled: !(location === null || location === void 0 ? void 0 : location.source),
126
+ folder: locationType === 'folder',
116
127
  onConfigureApps: () => {
117
128
  var _a;
118
129
  var _b;
@@ -128,11 +139,34 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location }) =>
128
139
  onOpenInEditor: (editorId) => {
129
140
  openWithEditor(editorId).catch(() => undefined);
130
141
  },
142
+ onOpenInFileExplorer: () => {
143
+ if (!(location === null || location === void 0 ? void 0 : location.source)) {
144
+ return;
145
+ }
146
+ (0, actions_1.openInFileExplorer)({ directory: location.source }).catch((err) => {
147
+ (0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
148
+ });
149
+ },
150
+ onOpenInTerminal: (terminalId) => {
151
+ if (!(location === null || location === void 0 ? void 0 : location.source) || locationType !== 'folder') {
152
+ return;
153
+ }
154
+ (0, open_in_editor_1.openInTerminal)(terminalId, location.source)
155
+ .then((response) => {
156
+ if (!response.success) {
157
+ (0, NotificationCenter_1.showNotification)('Could not open terminal', 2000);
158
+ }
159
+ })
160
+ .catch((err) => {
161
+ (0, NotificationCenter_1.showNotification)(`Could not open terminal: ${err.message}`, 2000);
162
+ });
163
+ },
131
164
  });
132
165
  }, [
133
166
  codingAgentInfo,
134
167
  editorInfo,
135
168
  location,
169
+ locationType,
136
170
  openWithCodingAgent,
137
171
  openWithEditor,
138
172
  preferredEditorId,
@@ -141,9 +175,16 @@ const InspectorOpenInEditor = ({ contextForAgents = null, label, location }) =>
141
175
  if (!editorPickerAvailable) {
142
176
  return null;
143
177
  }
144
- return (jsx_runtime_1.jsxs("div", { style: splitButton, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), children: [
178
+ return (jsx_runtime_1.jsxs("div", { style: splitButton, onPointerEnter: () => {
179
+ if (!ignorePointerEnter.current) {
180
+ setHovered(true);
181
+ }
182
+ }, onPointerLeave: () => {
183
+ ignorePointerEnter.current = false;
184
+ setHovered(false);
185
+ }, children: [
145
186
  jsx_runtime_1.jsxs("button", { "aria-label": `Open in ${editorName}`, disabled: !canOpenDefault, onClick: onOpenDefault, style: mainButtonStyle, tabIndex: tabIndex, title: `Open in ${editorName}`, type: "button", children: [label, jsx_runtime_1.jsx(editor_1.EditorIcon, { editorId: preferredEditorId, size: editorButtonIconSize })
146
- ] }), jsx_runtime_1.jsx(InlineDropdown_1.InlineDropdown, { onOpenChange: setDropdownOpened, renderAction: renderDropdownAction, style: dropdownStyle, title: "Open in another app", unhoveredColor: dropdownForegroundColor, values: menuItems, variant: "compact" })
187
+ ] }), jsx_runtime_1.jsx(InlineDropdown_1.InlineDropdown, { onOpenChange: onDropdownOpenChange, renderAction: renderDropdownAction, style: dropdownStyle, title: "Open in another app", unhoveredColor: dropdownForegroundColor, values: menuItems, variant: "compact" })
147
188
  ] }));
148
189
  };
149
190
  exports.InspectorOpenInEditor = InspectorOpenInEditor;
@@ -119,7 +119,7 @@ const AlignmentControls = ({ track }) => {
119
119
  shouldResortToDefaultValueIfUndefined: true,
120
120
  })) !== null && _c !== void 0 ? _c : fieldSchema.default) !== null && _d !== void 0 ? _d : '0px 0px')
121
121
  : String((_e = fieldSchema.default) !== null && _e !== void 0 ? _e : '0px 0px');
122
- const [currentX, currentY] = (0, timeline_translate_utils_1.parseTranslate)(currentTranslate);
122
+ const [currentX, currentY, currentZ] = (0, timeline_translate_utils_1.parseTranslate)(currentTranslate);
123
123
  const { x: newX, y: newY } = (0, alignment_controls_1.computeAlignedTranslate)({
124
124
  direction,
125
125
  elementRect,
@@ -128,7 +128,7 @@ const AlignmentControls = ({ track }) => {
128
128
  currentTranslateY: currentY,
129
129
  scale,
130
130
  });
131
- const newValue = (0, timeline_translate_utils_1.serializeTranslate)(newX, newY);
131
+ const newValue = (0, timeline_translate_utils_1.serializeTranslate)([newX, newY, currentZ]);
132
132
  const undoLabels = {
133
133
  left: 'Align left',
134
134
  'center-h': 'Align center horizontally',
@@ -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
  };
@@ -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
  };
@@ -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
  };
@@ -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);