@remotion/studio 4.0.516 → 4.0.517

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 (117) hide show
  1. package/dist/components/AssetSelector.js +1 -1
  2. package/dist/components/Canvas.js +15 -12
  3. package/dist/components/CanvasCaptureDropHandler.d.ts +4 -0
  4. package/dist/components/CanvasCaptureDropHandler.js +42 -0
  5. package/dist/components/CanvasOrLoading.js +4 -3
  6. package/dist/components/CaptionInspector.js +1 -1
  7. package/dist/components/CheckboardToggle.js +1 -1
  8. package/dist/components/Checkbox.d.ts +0 -1
  9. package/dist/components/Checkbox.js +2 -19
  10. package/dist/components/ConfigureLicenseModal.js +79 -46
  11. package/dist/components/CurrentAsset.d.ts +1 -1
  12. package/dist/components/CurrentAsset.js +9 -4
  13. package/dist/components/Editor.js +2 -1
  14. package/dist/components/EditorContent.js +5 -2
  15. package/dist/components/EditorContexts.js +2 -1
  16. package/dist/components/EditorRuler/Ruler.d.ts +1 -0
  17. package/dist/components/EditorRuler/Ruler.js +9 -8
  18. package/dist/components/EditorRuler/index.d.ts +1 -0
  19. package/dist/components/EditorRuler/index.js +3 -4
  20. package/dist/components/EditorRuler/use-is-ruler-visible.d.ts +1 -1
  21. package/dist/components/EditorRuler/use-is-ruler-visible.js +8 -2
  22. package/dist/components/ElementLibraryModal.d.ts +5 -0
  23. package/dist/components/ElementLibraryModal.js +38 -0
  24. package/dist/components/FilePreview.js +71 -0
  25. package/dist/components/InlineEditableTitle.js +2 -2
  26. package/dist/components/InspectorPanel/CompositionInspector.js +11 -38
  27. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +2 -2
  28. package/dist/components/InspectorPanel/CompositionMetadata.js +11 -4
  29. package/dist/components/InspectorPanel/EasingInspector.js +2 -2
  30. package/dist/components/InspectorPanel/ElementLibraryButton.d.ts +2 -0
  31. package/dist/components/InspectorPanel/ElementLibraryButton.js +139 -0
  32. package/dist/components/InspectorPanel/KeyframeInspector.js +1 -1
  33. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +12 -5
  34. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -3
  35. package/dist/components/InspectorPanel/common.d.ts +0 -1
  36. package/dist/components/InspectorPanel/common.js +3 -7
  37. package/dist/components/InspectorPanel/inspector-selection.d.ts +2 -2
  38. package/dist/components/InspectorPanel/styles.d.ts +0 -1
  39. package/dist/components/InspectorPanel/styles.js +3 -4
  40. package/dist/components/InspectorPanel/use-track-for-selection.d.ts +1 -2
  41. package/dist/components/InspectorSequenceSection.d.ts +1 -2
  42. package/dist/components/InspectorSourceLocation.js +1 -1
  43. package/dist/components/Menu/MenuItem.js +15 -6
  44. package/dist/components/MenuToolbar.js +7 -3
  45. package/dist/components/Modals.js +2 -1
  46. package/dist/components/PlaybackRateSelector.js +1 -1
  47. package/dist/components/Preview.js +83 -5
  48. package/dist/components/PreviewToolbar.js +10 -4
  49. package/dist/components/PreviewToolbarOverflowButton.d.ts +1 -0
  50. package/dist/components/PreviewToolbarOverflowButton.js +9 -2
  51. package/dist/components/RadioButton.d.ts +6 -0
  52. package/dist/components/RadioButton.js +62 -0
  53. package/dist/components/RenderButton.js +2 -1
  54. package/dist/components/RulersAndGuidesToggle.d.ts +3 -1
  55. package/dist/components/RulersAndGuidesToggle.js +18 -7
  56. package/dist/components/SelectedOutlinePolygon.d.ts +1 -2
  57. package/dist/components/SelectedOutlineRenderer.d.ts +1 -2
  58. package/dist/components/SelectedOutlineUvControls.d.ts +1 -1
  59. package/dist/components/SettingsModal.js +1 -1
  60. package/dist/components/SettingsModalFooter.d.ts +3 -1
  61. package/dist/components/SettingsModalFooter.js +19 -4
  62. package/dist/components/ShowPixelGridProvider.d.ts +4 -0
  63. package/dist/components/ShowPixelGridProvider.js +24 -0
  64. package/dist/components/SidebarCollapserControls.js +2 -2
  65. package/dist/components/Timeline/Timeline.js +41 -0
  66. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +6 -7
  67. package/dist/components/Timeline/TimelineDragHandler.js +11 -4
  68. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -2
  69. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +4 -2
  70. package/dist/components/Timeline/TimelineSelection.d.ts +29 -66
  71. package/dist/components/Timeline/TimelineSelection.js +30 -170
  72. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  73. package/dist/components/Timeline/TimelineSequenceItem.js +8 -6
  74. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +3 -4
  75. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +3 -4
  76. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +3 -4
  77. package/dist/components/Timeline/find-track-for-node-path-info.d.ts +1 -1
  78. package/dist/components/Timeline/keyframe-clipboard.d.ts +2 -3
  79. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +2 -3
  80. package/dist/components/Timeline/sequence-prop-clipboard.d.ts +2 -3
  81. package/dist/components/Timeline/split-selected-timeline-item.d.ts +2 -3
  82. package/dist/components/Timeline/timeline-expanded-filter.d.ts +1 -2
  83. package/dist/components/Timeline/timeline-scroll-logic.d.ts +7 -5
  84. package/dist/components/Timeline/timeline-scroll-logic.js +12 -7
  85. package/dist/components/Timeline/update-selected-easing.d.ts +7 -7
  86. package/dist/components/Timeline/use-timeline-asset-drop.js +24 -1
  87. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +6 -7
  88. package/dist/components/canvas-capture-drop.d.ts +4 -0
  89. package/dist/components/canvas-capture-drop.js +22 -0
  90. package/dist/components/selected-outline-measurement.d.ts +7 -8
  91. package/dist/esm/{chunk-w4244j4n.js → chunk-gzqm3g2m.js} +15184 -8344
  92. package/dist/esm/internals.mjs +15184 -8344
  93. package/dist/esm/previewEntry.mjs +15096 -8256
  94. package/dist/esm/renderEntry.mjs +1 -1
  95. package/dist/helpers/calculate-timeline.d.ts +1 -7
  96. package/dist/helpers/calculate-timeline.js +2 -146
  97. package/dist/helpers/editor-ruler.js +6 -5
  98. package/dist/helpers/get-asset-metadata.d.ts +19 -0
  99. package/dist/helpers/get-asset-metadata.js +51 -6
  100. package/dist/helpers/get-connected-compositions.d.ts +1 -6
  101. package/dist/helpers/get-connected-compositions.js +2 -8
  102. package/dist/helpers/get-sequence-visible-range.d.ts +1 -5
  103. package/dist/helpers/get-sequence-visible-range.js +6 -51
  104. package/dist/helpers/get-timeline-nestedness.d.ts +1 -2
  105. package/dist/helpers/get-timeline-nestedness.js +2 -12
  106. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -22
  107. package/dist/helpers/get-timeline-sequence-sort-key.js +2 -16
  108. package/dist/helpers/is-current-selected-still.js +4 -2
  109. package/dist/helpers/sort-by-nonce-history.d.ts +1 -5
  110. package/dist/helpers/sort-by-nonce-history.js +3 -148
  111. package/dist/helpers/timeline-node-path-key.d.ts +1 -2
  112. package/dist/helpers/timeline-node-path-key.js +2 -2
  113. package/dist/helpers/use-menu-structure.js +20 -0
  114. package/dist/state/editor-pixel-grid.d.ts +8 -0
  115. package/dist/state/editor-pixel-grid.js +18 -0
  116. package/dist/state/modals.d.ts +4 -0
  117. package/package.json +14 -12
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.InspectorDefaultPropsWarnings = exports.InspectorQuickAction = exports.InspectorDetailRow = exports.InspectorMessage = exports.InspectorBackAction = exports.InspectorSection = exports.InspectorQuickActionsSection = exports.InspectorSectionDivider = exports.InspectorSectionHeader = void 0;
6
+ exports.InspectorDefaultPropsWarnings = exports.InspectorQuickAction = exports.InspectorDetailRow = exports.InspectorMessage = exports.InspectorBackAction = exports.InspectorSection = exports.InspectorQuickActionsSection = exports.InspectorSectionHeader = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = __importDefault(require("react"));
9
9
  const colors_1 = require("../../helpers/colors");
@@ -14,15 +14,11 @@ const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
14
14
  const styles_1 = require("./styles");
15
15
  const InspectorSectionHeader = ({ children }) => jsx_runtime_1.jsx("div", { style: styles_1.sectionHeader, children: children });
16
16
  exports.InspectorSectionHeader = InspectorSectionHeader;
17
- const InspectorSectionDivider = () => (jsx_runtime_1.jsx("div", { style: styles_1.inspectorSectionDivider }));
18
- exports.InspectorSectionDivider = InspectorSectionDivider;
19
- const InspectorQuickActionsSection = ({ children }) => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
20
- jsx_runtime_1.jsx(exports.InspectorSectionDivider, {}), jsx_runtime_1.jsx("div", { style: styles_1.inspectorQuickActionsSection, children: children })
21
- ] }));
17
+ const InspectorQuickActionsSection = ({ children }) => jsx_runtime_1.jsx("div", { style: styles_1.inspectorQuickActionsSection, children: children });
22
18
  exports.InspectorQuickActionsSection = InspectorQuickActionsSection;
23
19
  const InspectorSection = ({ children, header }) => {
24
20
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
25
- jsx_runtime_1.jsx(exports.InspectorSectionDivider, {}), jsx_runtime_1.jsx(exports.InspectorSectionHeader, { children: header }), children === null ? null : (jsx_runtime_1.jsx("div", { style: styles_1.inspectorSectionBody, children: children }))] }));
21
+ jsx_runtime_1.jsx(exports.InspectorSectionHeader, { children: header }), children === null ? null : (jsx_runtime_1.jsx("div", { style: styles_1.inspectorSectionBody, children: children }))] }));
26
22
  };
27
23
  exports.InspectorSection = InspectorSection;
28
24
  const backArrowIcon = {
@@ -2,9 +2,9 @@ import { type TimelineSelection } from '../Timeline/TimelineSelection';
2
2
  export type SequenceSectionSelection = Extract<TimelineSelection, {
3
3
  type: 'sequence' | 'sequence-prop' | 'sequence-all-effects' | 'sequence-effect' | 'sequence-effect-prop';
4
4
  }>;
5
- export declare const isSequenceSectionSelection: (selection: TimelineSelection) => selection is SequenceSectionSelection;
5
+ export declare const isSequenceSectionSelection: (selection: import("@remotion/canvas").CanvasSelectionItem) => selection is SequenceSectionSelection;
6
6
  type SameSequenceInspectorSelection = Extract<TimelineSelection, {
7
7
  type: 'sequence-prop' | 'sequence-effect' | 'sequence-effect-prop';
8
8
  }>;
9
- export declare const getSameSequenceInspectorSelection: (selections: readonly TimelineSelection[]) => SameSequenceInspectorSelection | null;
9
+ export declare const getSameSequenceInspectorSelection: (selections: readonly import("@remotion/canvas").CanvasSelectionItem[]) => SameSequenceInspectorSelection | null;
10
10
  export {};
@@ -4,7 +4,6 @@ export declare const scrollableContainer: React.CSSProperties;
4
4
  export declare const compositionDefaultPropsSection: React.CSSProperties;
5
5
  export declare const compositionVisualControlsSection: React.CSSProperties;
6
6
  export declare const inspectorOverviewSection: React.CSSProperties;
7
- export declare const inspectorSectionDivider: React.CSSProperties;
8
7
  export declare const sequenceHeaderDivider: React.CSSProperties;
9
8
  export declare const sectionHeader: React.CSSProperties;
10
9
  export declare const inspectorSectionBody: React.CSSProperties;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.keyframeEditorValue = exports.keyframeEditorRow = exports.detailValue = exports.detailLabel = exports.detailRow = exports.guideDetailsContainer = exports.detailsBeforeInlineAction = exports.inspectorQuickActionsSection = exports.detailsWithInlineAction = exports.detailsContainer = exports.centeredMessage = exports.selectedContainer = exports.resolveLinkStyle = exports.defaultPropsWarningMessages = exports.defaultPropsWarningContainer = exports.sectionHeaderEnd = exports.sectionHeaderStart = exports.sectionHeaderTitle = exports.sectionHeaderRow = exports.sequenceHeaderSubtitle = exports.inspectorSectionBody = exports.sectionHeader = exports.sequenceHeaderDivider = exports.inspectorSectionDivider = exports.inspectorOverviewSection = exports.compositionVisualControlsSection = exports.compositionDefaultPropsSection = exports.scrollableContainer = exports.container = void 0;
3
+ exports.keyframeEditorValue = exports.keyframeEditorRow = exports.detailValue = exports.detailLabel = exports.detailRow = exports.guideDetailsContainer = exports.detailsBeforeInlineAction = exports.inspectorQuickActionsSection = exports.detailsWithInlineAction = exports.detailsContainer = exports.centeredMessage = exports.selectedContainer = exports.resolveLinkStyle = exports.defaultPropsWarningMessages = exports.defaultPropsWarningContainer = exports.sectionHeaderEnd = exports.sectionHeaderStart = exports.sectionHeaderTitle = exports.sectionHeaderRow = exports.sequenceHeaderSubtitle = exports.inspectorSectionBody = exports.sectionHeader = exports.sequenceHeaderDivider = exports.inspectorOverviewSection = exports.compositionVisualControlsSection = exports.compositionDefaultPropsSection = exports.scrollableContainer = exports.container = void 0;
4
4
  const colors_1 = require("../../helpers/colors");
5
5
  const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
6
+ const layout_1 = require("../layout");
6
7
  exports.container = {
7
8
  backgroundColor: colors_1.BACKGROUND,
8
9
  color: colors_1.WHITE,
@@ -29,9 +30,6 @@ exports.inspectorOverviewSection = {
29
30
  display: 'flex',
30
31
  flexDirection: 'column',
31
32
  };
32
- exports.inspectorSectionDivider = {
33
- borderBottom: `1px solid ${colors_1.LINE_COLOR}`,
34
- };
35
33
  exports.sequenceHeaderDivider = {
36
34
  backgroundColor: colors_1.LINE_COLOR,
37
35
  flexShrink: 0,
@@ -161,6 +159,7 @@ exports.detailRow = {
161
159
  display: 'flex',
162
160
  gap: 12,
163
161
  justifyContent: 'space-between',
162
+ minHeight: layout_1.COMPACT_CONTROL_ROW_HEIGHT,
164
163
  };
165
164
  exports.detailLabel = {
166
165
  color: colors_1.LIGHT_TEXT,
@@ -1,2 +1 @@
1
- import type { TimelineSelection } from '../Timeline/TimelineSelection';
2
- export declare const useTrackForSelection: (selection: TimelineSelection) => import("../../helpers/get-timeline-sequence-sort-key").TimelineTrackData | null;
1
+ export declare const useTrackForSelection: (selection: import("@remotion/canvas").CanvasSelectionItem) => import("@remotion/canvas").TimelineTrackData | null;
@@ -3,11 +3,10 @@ import { type TSequence } from 'remotion';
3
3
  import type { CodePosition } from '../error-overlay/react-overlay/utils/get-source-map';
4
4
  import type { SequenceNodePathInfo } from '../helpers/get-timeline-sequence-sort-key';
5
5
  import { type FlatTreeRow } from '../helpers/timeline-layout';
6
- import { type TimelineSelection } from './Timeline/TimelineSelection';
7
6
  type SequenceWithControls = TSequence & {
8
7
  readonly controls: NonNullable<TSequence['controls']>;
9
8
  };
10
- export declare const getInspectorSelectableItems: (rows: readonly FlatTreeRow[]) => TimelineSelection[];
9
+ export declare const getInspectorSelectableItems: (rows: readonly FlatTreeRow[]) => import("@remotion/canvas").CanvasSelectionItem[];
11
10
  export declare const hasSequenceControls: (sequence: TSequence) => sequence is SequenceWithControls;
12
11
  export declare const InspectorSequenceSection: React.FC<{
13
12
  readonly sequence: SequenceWithControls;
@@ -82,7 +82,7 @@ const InspectorSourceLocation = ({ location, canOpen, onOpen, renderIcon, size =
82
82
  return null;
83
83
  }
84
84
  if (size === 'quick-action') {
85
- return (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: !canOpen, onClick: onClick, renderIcon: (iconColor) => renderIcon === null || renderIcon === void 0 ? void 0 : renderIcon(iconColor), size: "compact", title: fileLocation !== null && fileLocation !== void 0 ? fileLocation : undefined, children: label }));
85
+ return (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: !canOpen, onClick: onClick, renderIcon: (iconColor) => renderIcon === null || renderIcon === void 0 ? void 0 : renderIcon(iconColor), title: fileLocation !== null && fileLocation !== void 0 ? fileLocation : undefined, children: label }));
86
86
  }
87
87
  return (jsx_runtime_1.jsxs("button", { type: "button", style: style, title: fileLocation !== null && fileLocation !== void 0 ? fileLocation : undefined, onClick: onClick, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), children: [renderIcon ? renderIcon(color) : null, jsx_runtime_1.jsx("span", { style: sourceLocationLabelStyle, children: label })
88
88
  ] }));
@@ -12,20 +12,29 @@ const colors_1 = require("../../helpers/colors");
12
12
  const hoverable_1 = require("../../helpers/hoverable");
13
13
  const pointer_session_1 = require("../../helpers/pointer-session");
14
14
  const z_index_1 = require("../../state/z-index");
15
+ const menu_toolbar_height_1 = require("../menu-toolbar-height");
15
16
  const MenuContent_1 = require("../NewComposition/MenuContent");
16
17
  const is_menu_item_1 = require("./is-menu-item");
17
18
  const portals_1 = require("./portals");
18
19
  const styles_1 = require("./styles");
20
+ const MENU_ITEM_HEIGHT = 24;
21
+ const MENU_ITEM_VERTICAL_MARGIN = (menu_toolbar_height_1.MENU_TOOLBAR_HEIGHT - MENU_ITEM_HEIGHT) / 2;
19
22
  const container = {
23
+ alignItems: 'center',
24
+ boxSizing: 'border-box',
25
+ display: 'inline-flex',
20
26
  fontSize: 13,
21
- paddingLeft: 10,
22
- paddingRight: 10,
27
+ height: MENU_ITEM_HEIGHT,
28
+ justifyContent: 'center',
29
+ paddingLeft: 8,
30
+ paddingRight: 8,
23
31
  cursor: 'default',
24
- paddingTop: 6,
25
- paddingBottom: 6,
32
+ paddingTop: 0,
33
+ paddingBottom: 0,
26
34
  userSelect: 'none',
27
35
  WebkitUserSelect: 'none',
28
36
  border: 'none',
37
+ borderRadius: 3,
29
38
  };
30
39
  const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered, onItemQuit, onPreviousMenu, onNextMenu, menu, }) => {
31
40
  const ref = (0, react_1.useRef)(null);
@@ -58,7 +67,7 @@ const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered
58
67
  return {
59
68
  ...styles_1.menuContainerTowardsBottom,
60
69
  left: size.left,
61
- top: size.top + size.height,
70
+ top: size.top + size.height + MENU_ITEM_VERTICAL_MARGIN,
62
71
  };
63
72
  }, [selected, size]);
64
73
  // Not for styling (which is done via CSS :hover), but for switching
@@ -105,7 +114,7 @@ const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered
105
114
  var _a, _b;
106
115
  return {
107
116
  ...styles_1.outerPortal,
108
- top: ((_a = size === null || size === void 0 ? void 0 : size.top) !== null && _a !== void 0 ? _a : 0) + ((_b = size === null || size === void 0 ? void 0 : size.height) !== null && _b !== void 0 ? _b : 0),
117
+ top: ((_a = size === null || size === void 0 ? void 0 : size.top) !== null && _a !== void 0 ? _a : 0) + ((_b = size === null || size === void 0 ? void 0 : size.height) !== null && _b !== void 0 ? _b : 0) + MENU_ITEM_VERTICAL_MARGIN,
109
118
  };
110
119
  }, [size]);
111
120
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
@@ -36,6 +36,10 @@ const row = {
36
36
  const flex = {
37
37
  flex: 1,
38
38
  };
39
+ const menuItems = {
40
+ display: 'inline-flex',
41
+ height: 24,
42
+ };
39
43
  const MenuToolbar = ({ readOnlyStudio }) => {
40
44
  const [selected, setSelected] = (0, react_1.useState)(null);
41
45
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
@@ -126,9 +130,9 @@ const MenuToolbar = ({ readOnlyStudio }) => {
126
130
  ? 'Quick Switcher'
127
131
  : `Quick Switcher (${ShortcutHint_1.cmdOrCtrlCharacter}+K)`;
128
132
  return (jsx_runtime_1.jsxs(layout_1.Row, { align: "center", className: "css-reset", style: row, onPointerDown: onPointerDown, children: [
129
- jsx_runtime_1.jsxs("div", { style: fixedWidthLeft, children: [mobileLayout ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: openQuickSwitcher, renderAction: renderSearchIcon, title: searchTooltip })) : (jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "left" })), structure.map((s) => {
130
- return (jsx_runtime_1.jsx(MenuItem_1.MenuItem, { selected: selected === s.id, onItemSelected: itemClicked, onItemHovered: itemHovered, id: s.id, label: s.label, onItemQuit: onItemQuit, menu: s, onPreviousMenu: onPreviousMenu, onNextMenu: onNextMenu, leaveLeftPadding: s.leaveLeftPadding }, s.id));
131
- }), readOnlyStudio || browserStudioOperations ? null : jsx_runtime_1.jsx(UpdateCheck_1.UpdateCheck, {})] }), mobileLayout ? null : jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsx(MenuBuildIndicator_1.MenuBuildIndicator, { mobileLayout: mobileLayout }), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsxs("div", { style: fixedWidthRight, children: [canUndoAndRedo ? jsx_runtime_1.jsx(UndoRedoButtons_1.UndoRedoButtons, {}) : null, jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "right" })
133
+ jsx_runtime_1.jsxs("div", { style: fixedWidthLeft, children: [mobileLayout ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: openQuickSwitcher, renderAction: renderSearchIcon, title: searchTooltip })) : (jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "left" })), jsx_runtime_1.jsx("div", { style: menuItems, children: structure.map((s) => {
134
+ return (jsx_runtime_1.jsx(MenuItem_1.MenuItem, { selected: selected === s.id, onItemSelected: itemClicked, onItemHovered: itemHovered, id: s.id, label: s.label, onItemQuit: onItemQuit, menu: s, onPreviousMenu: onPreviousMenu, onNextMenu: onNextMenu, leaveLeftPadding: s.leaveLeftPadding }, s.id));
135
+ }) }), readOnlyStudio || browserStudioOperations ? null : jsx_runtime_1.jsx(UpdateCheck_1.UpdateCheck, {})] }), mobileLayout ? null : jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsx(MenuBuildIndicator_1.MenuBuildIndicator, { mobileLayout: mobileLayout }), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsxs("div", { style: fixedWidthRight, children: [canUndoAndRedo ? jsx_runtime_1.jsx(UndoRedoButtons_1.UndoRedoButtons, {}) : null, jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControl, { side: "right" })
132
136
  ] })
133
137
  ] }));
134
138
  };
@@ -13,6 +13,7 @@ const modals_1 = require("../state/modals");
13
13
  const AskAiModal_1 = require("./AskAiModal");
14
14
  const ConfirmationDialog_1 = require("./ConfirmationDialog");
15
15
  const EffectPickerModal_1 = require("./EffectPickerModal");
16
+ const ElementLibraryModal_1 = require("./ElementLibraryModal");
16
17
  const FixComputedValueModal_1 = require("./FixComputedValueModal");
17
18
  const DeleteComposition_1 = require("./NewComposition/DeleteComposition");
18
19
  const DeleteFolder_1 = require("./NewComposition/DeleteFolder");
@@ -58,6 +59,6 @@ const Modals = ({ readOnlyStudio }) => {
58
59
  modalContextType.initialTab === 'packages' ||
59
60
  modalContextType.initialTab === 'shortcuts') ? (jsx_runtime_1.jsx(SettingsModal_1.SettingsModal, { initialTab: modalContextType.initialTab, initialPublicLicenseKey: modalContextType.initialPublicLicenseKey }, `${modalContextType.initialTab}-${modalContextType.initialPublicLicenseKey}`)) : null, modalContextType && modalContextType.type === 'web-render' && (jsx_runtime_1.jsx(WebRenderModal_1.WebRenderModalWithLoader, { ...modalContextType })), modalContextType &&
60
61
  modalContextType.type === 'server-render' &&
61
- (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 === 'fix-computed-value' && (jsx_runtime_1.jsx(FixComputedValueModal_1.FixComputedValueModal, { state: modalContextType })), 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, {})] }));
62
+ (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 === 'fix-computed-value' && (jsx_runtime_1.jsx(FixComputedValueModal_1.FixComputedValueModal, { state: modalContextType })), 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 === 'element-library' && (jsx_runtime_1.jsx(ElementLibraryModal_1.ElementLibraryModal, { name: modalContextType.name, url: modalContextType.url })), 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, {})] }));
62
63
  };
63
64
  exports.Modals = Modals;
@@ -57,7 +57,7 @@ const PlaybackRateSelector = ({ playbackRate, setPlaybackRate, }) => {
57
57
  playbackRate,
58
58
  setPlaybackRate,
59
59
  });
60
- if (isStill || canvasContent === null || canvasContent.type === 'asset') {
60
+ if (isStill || canvasContent === null) {
61
61
  return null;
62
62
  }
63
63
  return (jsx_runtime_1.jsx(TimelineCombobox_1.TimelineCombobox, { title: accessibilityLabel, labelWidth: 30, selectedId: selectedId, values: items, renderLeftItem: (color) => (jsx_runtime_1.jsx(playback_rate_1.PlaybackRateIcon, { color: color, playbackRate: playbackRate })), unhoveredIconColor: colors_1.WHITE_ALPHA_80 }));
@@ -2,15 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VideoPreview = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const media_1 = require("@remotion/media");
5
6
  const player_1 = require("@remotion/player");
6
7
  const react_1 = require("react");
8
+ const react_dom_1 = require("react-dom");
7
9
  const remotion_1 = require("remotion");
8
10
  const ErrorLoader_1 = require("../error-overlay/remotion-overlay/ErrorLoader");
11
+ const add_asset_cache_bust_1 = require("../helpers/add-asset-cache-bust");
9
12
  const checkerboard_background_1 = require("../helpers/checkerboard-background");
10
13
  const colors_1 = require("../helpers/colors");
11
14
  const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
12
15
  const studio_fit_padding_1 = require("../helpers/studio-fit-padding");
16
+ const audio_1 = require("../icons/audio");
13
17
  const checkerboard_1 = require("../state/checkerboard");
18
+ const editor_pixel_grid_1 = require("../state/editor-pixel-grid");
14
19
  const is_menu_item_1 = require("./Menu/is-menu-item");
15
20
  const RenderPreview_1 = require("./RenderPreview");
16
21
  const SelectedOutlineOverlay_1 = require("./SelectedOutlineOverlay");
@@ -38,9 +43,13 @@ const assetMetadataErrorContainer = {
38
43
  overflowY: 'auto',
39
44
  };
40
45
  const checkerboardSize = 49;
46
+ const PIXEL_GRID_MIN_SCALE = 4;
41
47
  const containerStyle = (options) => {
42
48
  return {
43
49
  transform: `scale(${options.scale})`,
50
+ // Avoid the background bleeding through opaque compositions at fractional
51
+ // scales due to Chromium compositing the child and background together.
52
+ willChange: 'transform',
44
53
  marginLeft: options.xCorrection,
45
54
  marginTop: options.yCorrection,
46
55
  width: options.width,
@@ -54,6 +63,20 @@ const containerStyle = (options) => {
54
63
  backgroundPosition: (0, checkerboard_background_1.getCheckerboardBackgroundPos)(checkerboardSize) /* Must be half of one side of the square */,
55
64
  };
56
65
  };
66
+ const PixelGrid = ({ scale }) => {
67
+ const { editorShowPixelGrid } = (0, react_1.useContext)(editor_pixel_grid_1.EditorShowPixelGridContext);
68
+ if (!editorShowPixelGrid || scale < PIXEL_GRID_MIN_SCALE) {
69
+ return null;
70
+ }
71
+ return (jsx_runtime_1.jsx("div", { "aria-hidden": "true", className: "css-reset", "data-testid": "pixel-grid", style: {
72
+ position: 'absolute',
73
+ inset: 0,
74
+ pointerEvents: 'none',
75
+ opacity: 0.35,
76
+ backgroundImage: `linear-gradient(to right, ${colors_1.RULER_COLOR} 1px, transparent 1px), linear-gradient(to bottom, ${colors_1.RULER_COLOR} 1px, transparent 1px)`,
77
+ backgroundSize: `${scale}px ${scale}px`,
78
+ } }));
79
+ };
57
80
  const VideoPreview = ({ canvasSize, contentDimensions, canvasContent, assetMetadata, onRetryAssetMetadata, }) => {
58
81
  if (assetMetadata && assetMetadata.type === 'not-found') {
59
82
  return (jsx_runtime_1.jsx("div", { style: centeredContainer, children: jsx_runtime_1.jsx("div", { style: label, children: "File does not exist" }) }));
@@ -61,7 +84,8 @@ const VideoPreview = ({ canvasSize, contentDimensions, canvasContent, assetMetad
61
84
  if (assetMetadata && assetMetadata.type === 'metadata-error') {
62
85
  return (jsx_runtime_1.jsx("div", { style: assetMetadataErrorContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: jsx_runtime_1.jsx(ErrorLoader_1.ErrorLoader, { canHaveDismissButton: false, keyboardShortcuts: false, error: assetMetadata.error, onRetry: onRetryAssetMetadata !== null && onRetryAssetMetadata !== void 0 ? onRetryAssetMetadata : null, calculateMetadata: false }, assetMetadata.error.stack) }));
63
86
  }
64
- if (contentDimensions === null) {
87
+ if (contentDimensions === null ||
88
+ (canvasContent.type !== 'composition' && assetMetadata === null)) {
65
89
  return (jsx_runtime_1.jsx("div", { style: centeredContainer, children: jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: 24 }) }));
66
90
  }
67
91
  return (jsx_runtime_1.jsx(CompWhenItHasDimensions, { contentDimensions: contentDimensions, canvasSize: canvasSize, canvasContent: canvasContent, assetMetadata: assetMetadata }));
@@ -69,6 +93,7 @@ const VideoPreview = ({ canvasSize, contentDimensions, canvasContent, assetMetad
69
93
  exports.VideoPreview = VideoPreview;
70
94
  const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent, assetMetadata }) => {
71
95
  const { size: previewSize } = (0, react_1.useContext)(remotion_1.Internals.PreviewSizeContext);
96
+ const { currentAssetMetadata } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
72
97
  const [canvasHovered, setCanvasHovered] = (0, react_1.useState)(false);
73
98
  const compositionContainerRef = (0, react_1.useRef)(null);
74
99
  (0, react_1.useEffect)(() => {
@@ -111,6 +136,17 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
111
136
  previewSize: previewSize.size,
112
137
  });
113
138
  }, [canvasContent.type, canvasSize, contentDimensions, previewSize.size]);
139
+ const assetFileType = canvasContent.type === 'asset'
140
+ ? (0, get_preview_file_type_1.getPreviewFileType)(canvasContent.asset)
141
+ : null;
142
+ const mediaCompositionFileType = (assetFileType === 'audio' || assetFileType === 'video') &&
143
+ (assetMetadata === null || assetMetadata === void 0 ? void 0 : assetMetadata.type) === 'found' &&
144
+ assetMetadata.mediaMetadata !== null &&
145
+ canvasContent.type === 'asset' &&
146
+ (currentAssetMetadata === null || currentAssetMetadata === void 0 ? void 0 : currentAssetMetadata.asset) === canvasContent.asset &&
147
+ contentDimensions !== 'none'
148
+ ? assetFileType
149
+ : null;
114
150
  const outer = (0, react_1.useMemo)(() => {
115
151
  return {
116
152
  width: contentDimensions === 'none' ? '100%' : contentDimensions.width * scale,
@@ -123,9 +159,12 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
123
159
  left: centerX - previewSize.translation.x,
124
160
  top: centerY - previewSize.translation.y,
125
161
  overflow: canvasContent.type === 'composition' ? 'visible' : 'hidden',
126
- justifyContent: canvasContent.type === 'asset' ? 'center' : 'flex-start',
162
+ justifyContent: canvasContent.type === 'asset' && mediaCompositionFileType === null
163
+ ? 'center'
164
+ : 'flex-start',
127
165
  alignItems: canvasContent.type === 'asset' &&
128
- (0, get_preview_file_type_1.getPreviewFileType)(canvasContent.asset) === 'audio'
166
+ mediaCompositionFileType === null &&
167
+ assetFileType === 'audio'
129
168
  ? 'center'
130
169
  : 'normal',
131
170
  };
@@ -137,8 +176,25 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
137
176
  previewSize.translation.y,
138
177
  centerY,
139
178
  canvasContent,
179
+ mediaCompositionFileType,
180
+ assetFileType,
140
181
  ]);
141
182
  if (canvasContent.type === 'asset') {
183
+ if (mediaCompositionFileType !== null &&
184
+ (assetMetadata === null || assetMetadata === void 0 ? void 0 : assetMetadata.type) === 'found' &&
185
+ contentDimensions !== 'none') {
186
+ return (jsx_runtime_1.jsxs("div", { ref: compositionContainerRef, className: "remotion-studio-composition-container", style: outer, children: [mediaCompositionFileType === 'audio' ? (jsx_runtime_1.jsx(audio_1.AudioFileIcon, { "aria-label": "Audio asset", color: colors_1.LIGHT_TEXT, role: "img", style: {
187
+ height: 64,
188
+ left: '50%',
189
+ opacity: 0.25,
190
+ pointerEvents: 'none',
191
+ position: 'absolute',
192
+ top: '50%',
193
+ transform: 'translate(-50%, -50%)',
194
+ width: 64,
195
+ } })) : null, jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, offscreen: mediaCompositionFileType === 'audio', scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(AssetMediaComposition, { asset: canvasContent.asset, fetchedAt: assetMetadata.fetchedAt, fileType: mediaCompositionFileType })
196
+ ] }));
197
+ }
142
198
  return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(StaticFilePreview_1.StaticFilePreview, { assetMetadata: assetMetadata, currentAsset: canvasContent.asset }) }));
143
199
  }
144
200
  if (canvasContent.type === 'output') {
@@ -148,14 +204,35 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
148
204
  return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(RenderPreview_1.RenderPreview, { path: canvasContent.displayName, assetMetadata: assetMetadata, getBlob: canvasContent.getBlob }) }));
149
205
  }
150
206
  return (jsx_runtime_1.jsxs("div", { ref: compositionContainerRef, className: "remotion-studio-composition-container", style: outer, children: [
151
- jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { canvasHovered: canvasHovered, compositionHeight: contentDimensions.height, compositionWidth: contentDimensions.width, scale: scale, translationX: previewSize.translation.x, translationY: previewSize.translation.y })
207
+ jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, offscreen: false, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(PixelGrid, { scale: scale }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { canvasHovered: canvasHovered, compositionHeight: contentDimensions.height, compositionWidth: contentDimensions.width, scale: scale, translationX: previewSize.translation.x, translationY: previewSize.translation.y })
152
208
  ] }));
153
209
  };
154
- const PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions }) => {
210
+ const AssetMediaComposition = ({ asset, fetchedAt, fileType }) => {
211
+ const src = (0, add_asset_cache_bust_1.addAssetCacheBust)({
212
+ fetchedAt,
213
+ src: (0, remotion_1.staticFile)(asset),
214
+ });
215
+ const style = {
216
+ width: '100%',
217
+ height: '100%',
218
+ };
219
+ return (0, react_dom_1.createPortal)(jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.DisableInteractivityProvider, { children: jsx_runtime_1.jsx("div", { "data-testid": "asset-media-preview", style: style, children: fileType === 'video' ? (jsx_runtime_1.jsx(media_1.Video, { name: asset, src: src, style: style })) : (jsx_runtime_1.jsx(media_1.Audio, { name: asset, src: src })) }) }) }), remotion_1.Internals.portalNode());
220
+ };
221
+ const PortalContainer = ({ offscreen, scale, xCorrection, yCorrection, contentDimensions }) => {
155
222
  const { checkerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
156
223
  const { clearSelection } = (0, TimelineSelection_1.useTimelineSelection)();
157
224
  const portalContainer = (0, react_1.useRef)(null);
158
225
  const style = (0, react_1.useMemo)(() => {
226
+ if (offscreen) {
227
+ return {
228
+ height: contentDimensions.height,
229
+ left: -999999,
230
+ overflow: 'hidden',
231
+ position: 'fixed',
232
+ top: 0,
233
+ width: contentDimensions.width,
234
+ };
235
+ }
159
236
  return containerStyle({
160
237
  checkerboard,
161
238
  scale,
@@ -168,6 +245,7 @@ const PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions })
168
245
  checkerboard,
169
246
  contentDimensions.height,
170
247
  contentDimensions.width,
248
+ offscreen,
171
249
  scale,
172
250
  xCorrection,
173
251
  yCorrection,
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const check_fullscreen_support_1 = require("../helpers/check-fullscreen-support");
8
8
  const colors_1 = require("../helpers/colors");
9
+ const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
9
10
  const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
10
11
  const mobile_layout_1 = require("../helpers/mobile-layout");
11
12
  const timeline_layout_1 = require("../helpers/timeline-layout");
@@ -74,6 +75,10 @@ const PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
74
75
  const { setPlayerMuted } = (0, react_1.useContext)(remotion_1.Internals.SetMediaVolumeContext);
75
76
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
76
77
  const isVideoComposition = (0, is_current_selected_still_1.useIsVideoComposition)();
78
+ const showCompositionControls = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition';
79
+ const showCanvasViewControls = showCompositionControls ||
80
+ ((canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'asset' &&
81
+ (0, get_preview_file_type_1.getPreviewFileType)(canvasContent.asset) === 'video');
77
82
  const isStill = (0, is_current_selected_still_1.useIsStill)();
78
83
  const [loop, setLoop] = (0, react_1.useState)((0, loop_1.loadLoopOption)());
79
84
  const isFullscreenSupported = (0, check_fullscreen_support_1.checkFullscreenSupport)();
@@ -84,12 +89,13 @@ const PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
84
89
  jsx_runtime_1.jsx("div", { style: padding }), isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(SizeSelector_1.SizeSelector, {}) })), !isMobileLayout && (isStill || isVideoComposition) ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
85
90
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate }) })
86
91
  ] })) : null, isMobileLayout ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
87
- jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(PreviewToolbarOverflowButton_1.PreviewToolbarOverflowButton, { showFullscreen: Boolean(canvasContent && isFullscreenSupported), showPlaybackRate: isVideoComposition, showLoop: isVideoComposition, showCompositionControls: (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition', playbackRate: playbackRate, setPlaybackRate: setPlaybackRate, loop: loop, setLoop: setLoop }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
92
+ jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(PreviewToolbarOverflowButton_1.PreviewToolbarOverflowButton, { showFullscreen: Boolean(canvasContent && isFullscreenSupported), showPlaybackRate: isVideoComposition, showLoop: isVideoComposition, showCanvasViewControls: showCanvasViewControls, showCompositionControls: showCompositionControls, playbackRate: playbackRate, setPlaybackRate: setPlaybackRate, loop: loop, setLoop: setLoop }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
88
93
  ] })) : null, isVideoComposition && isMobileLayout ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(MuteToggle_1.MuteToggle, { muted: playerMuted, setMuted: setPlayerMuted }) })) : null] }), jsx_runtime_1.jsx(layout_1.Flex, {}), isVideoComposition && isMobileLayout ? (jsx_runtime_1.jsx("div", { style: centeredPlayButton, children: playPause })) : null, isVideoComposition && !isMobileLayout ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
89
94
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), playPause, jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.75 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(MuteToggle_1.MuteToggle, { muted: playerMuted, setMuted: setPlayerMuted }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(TimelineInOutToggle_1.TimelineInOutPointToggle, {}) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 })
90
- ] })) : null, (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(CheckboardToggle_1.CheckboardToggle, {}) })), isMobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }), isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(OutlineToggle_1.OutlineToggle, {}) })), isMobileLayout ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
91
- jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RulersAndGuidesToggle_1.RulersAndGuidesToggle, {}) })
92
- ] })), readOnlyStudio || isMobileLayout ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
95
+ ] })) : null, showCanvasViewControls ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [isMobileLayout ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(CheckboardToggle_1.CheckboardToggle, {}) })), isMobileLayout ? null : jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }), isMobileLayout || !showCompositionControls ? null : (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(OutlineToggle_1.OutlineToggle, {}) })), isMobileLayout ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showCompositionControls ? jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }) : null, jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RulersAndGuidesToggle_1.RulersAndGuidesToggle, { showGuides: showCompositionControls }) })
96
+ ] })), readOnlyStudio ||
97
+ isMobileLayout ||
98
+ !showCompositionControls ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
93
99
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.25 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(SnappingToggle_1.SnappingToggle, {}) })
94
100
  ] }))] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), canvasContent && isFullscreenSupported ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(FullscreenToggle_1.FullScreenToggle, { hidden: isMobileLayout }) })) : null, jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsxs("div", { style: sideContainer, children: [
95
101
  jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RenderButton_1.RenderButton, { readOnlyStudio: readOnlyStudio, size: "compact", narrow: isMobileLayout }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
@@ -3,6 +3,7 @@ export declare const PreviewToolbarOverflowButton: React.FC<{
3
3
  readonly showFullscreen: boolean;
4
4
  readonly showPlaybackRate: boolean;
5
5
  readonly showLoop: boolean;
6
+ readonly showCanvasViewControls: boolean;
6
7
  readonly showCompositionControls: boolean;
7
8
  readonly playbackRate: number;
8
9
  readonly setPlaybackRate: React.Dispatch<React.SetStateAction<number>>;
@@ -19,7 +19,7 @@ const clickButton = (id) => {
19
19
  var _a;
20
20
  (_a = document.getElementById(id)) === null || _a === void 0 ? void 0 : _a.click();
21
21
  };
22
- const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLoop, showCompositionControls, playbackRate, setPlaybackRate, loop, setLoop, }) => {
22
+ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLoop, showCanvasViewControls, showCompositionControls, playbackRate, setPlaybackRate, loop, setLoop, }) => {
23
23
  const keyboardShortcutsDisabled = (0, use_keybinding_1.areKeyboardShortcutsDisabled)();
24
24
  const { checkerboard, setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
25
25
  const { editorShowOutlines, setEditorShowOutlines } = (0, react_1.useContext)(editor_outlines_1.EditorShowOutlinesContext);
@@ -86,7 +86,7 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
86
86
  quickSwitcherLabel: null,
87
87
  });
88
88
  }
89
- if (showCompositionControls) {
89
+ if (showCanvasViewControls) {
90
90
  items.push({
91
91
  type: 'item',
92
92
  id: 'checkerboard',
@@ -98,6 +98,8 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
98
98
  subMenu: null,
99
99
  quickSwitcherLabel: null,
100
100
  });
101
+ }
102
+ if (showCompositionControls) {
101
103
  items.push({
102
104
  type: 'item',
103
105
  id: 'outlines',
@@ -109,6 +111,8 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
109
111
  subMenu: null,
110
112
  quickSwitcherLabel: null,
111
113
  });
114
+ }
115
+ if (showCanvasViewControls) {
112
116
  items.push({
113
117
  type: 'item',
114
118
  id: 'rulers',
@@ -120,6 +124,8 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
120
124
  subMenu: null,
121
125
  quickSwitcherLabel: null,
122
126
  });
127
+ }
128
+ if (showCompositionControls) {
123
129
  items.push({
124
130
  type: 'item',
125
131
  id: 'guides',
@@ -154,6 +160,7 @@ const PreviewToolbarOverflowButton = ({ showFullscreen, showPlaybackRate, showLo
154
160
  showFullscreen,
155
161
  showLoop,
156
162
  showPlaybackRate,
163
+ showCanvasViewControls,
157
164
  showCompositionControls,
158
165
  loop,
159
166
  checkerboard,
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare const RadioButton: React.FC<{
3
+ readonly checked: boolean;
4
+ readonly children: React.ReactNode;
5
+ readonly onClick: () => void;
6
+ }>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RadioButton = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const colors_1 = require("../helpers/colors");
6
+ const hoverable_1 = require("../helpers/hoverable");
7
+ const row = {
8
+ ...(0, hoverable_1.hoverableStyle)({
9
+ idleBackground: colors_1.TRANSPARENT,
10
+ hoverBackground: (0, colors_1.getBackgroundFromHoverState)({
11
+ hovered: true,
12
+ selected: false,
13
+ }),
14
+ idleColor: colors_1.LIGHT_TEXT,
15
+ hoverColor: colors_1.WHITE,
16
+ }),
17
+ alignItems: 'center',
18
+ appearance: 'none',
19
+ border: 'none',
20
+ borderRadius: 4,
21
+ boxSizing: 'border-box',
22
+ cursor: 'default',
23
+ display: 'flex',
24
+ fontFamily: 'sans-serif',
25
+ fontSize: 14,
26
+ gap: 8,
27
+ lineHeight: '20px',
28
+ margin: '5px -8px',
29
+ padding: '4px 8px',
30
+ textAlign: 'left',
31
+ userSelect: 'none',
32
+ width: 'calc(100% + 16px)',
33
+ };
34
+ const circle = {
35
+ alignItems: 'center',
36
+ border: `1px solid ${colors_1.CURRENT_COLOR}`,
37
+ borderRadius: '50%',
38
+ boxSizing: 'border-box',
39
+ display: 'flex',
40
+ flexShrink: 0,
41
+ height: 20,
42
+ justifyContent: 'center',
43
+ width: 20,
44
+ };
45
+ const bullet = {
46
+ backgroundColor: colors_1.CURRENT_COLOR,
47
+ borderRadius: '50%',
48
+ height: 8,
49
+ width: 8,
50
+ };
51
+ const label = {
52
+ color: 'inherit',
53
+ fontFamily: 'sans-serif',
54
+ fontSize: 14,
55
+ lineHeight: '20px',
56
+ };
57
+ const RadioButton = ({ checked, children, onClick }) => {
58
+ return (jsx_runtime_1.jsxs("button", { "aria-checked": checked, className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, onClick: onClick, role: "radio", style: row, type: "button", children: [
59
+ jsx_runtime_1.jsx("span", { style: circle, children: checked ? jsx_runtime_1.jsx("span", { style: bullet }) : null }), jsx_runtime_1.jsx("span", { style: label, children: children })
60
+ ] }));
61
+ };
62
+ exports.RadioButton = RadioButton;
@@ -142,6 +142,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
142
142
  };
143
143
  }, [controlSize]);
144
144
  const video = remotion_1.Internals.useVideo();
145
+ const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
145
146
  const { getCurrentFrame } = player_1.PlayerInternals.usePlayerMethods();
146
147
  const { props } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
147
148
  // Read the frame when the modal opens instead of subscribing this button to
@@ -387,7 +388,7 @@ const RenderButtonInner = ({ readOnlyStudio, size: controlSize = 'default', narr
387
388
  showRenderLabel,
388
389
  tooltip,
389
390
  ]);
390
- if (!video) {
391
+ if (!video || (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition') {
391
392
  return null;
392
393
  }
393
394
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
@@ -1,2 +1,4 @@
1
1
  import React from 'react';
2
- export declare const RulersAndGuidesToggle: React.FC;
2
+ export declare const RulersAndGuidesToggle: React.FC<{
3
+ readonly showGuides: boolean;
4
+ }>;