@remotion/studio 4.0.472 → 4.0.474

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 (165) hide show
  1. package/dist/api/rename-static-file.d.ts +6 -0
  2. package/dist/api/rename-static-file.js +18 -0
  3. package/dist/components/AssetSelector.js +45 -4
  4. package/dist/components/AssetSelectorItem.js +177 -27
  5. package/dist/components/Canvas.js +131 -11
  6. package/dist/components/ConfirmationDialog-types.d.ts +8 -0
  7. package/dist/components/ConfirmationDialog-types.js +2 -0
  8. package/dist/components/ConfirmationDialog.d.ts +7 -0
  9. package/dist/components/ConfirmationDialog.js +103 -0
  10. package/dist/components/ContextMenu.d.ts +9 -1
  11. package/dist/components/ContextMenu.js +49 -5
  12. package/dist/components/CurrentAsset.d.ts +1 -0
  13. package/dist/components/CurrentAsset.js +13 -2
  14. package/dist/components/EditorContent.js +15 -2
  15. package/dist/components/EditorContexts.js +2 -1
  16. package/dist/components/EditorRuler/Ruler.js +2 -0
  17. package/dist/components/ExplorerPanel.d.ts +0 -4
  18. package/dist/components/ExplorerPanel.js +8 -4
  19. package/dist/components/ExplorerPanelRef.d.ts +4 -0
  20. package/dist/components/ExplorerPanelRef.js +5 -0
  21. package/dist/components/FilePreview.d.ts +1 -1
  22. package/dist/components/InitialCompositionLoader.d.ts +0 -1
  23. package/dist/components/InitialCompositionLoader.js +5 -27
  24. package/dist/components/Menu/MenuItem.js +7 -1
  25. package/dist/components/Menu/SubMenu.js +5 -1
  26. package/dist/components/Menu/portals.js +17 -8
  27. package/dist/components/MenuToolbar.js +5 -1
  28. package/dist/components/ModalContainer.js +6 -1
  29. package/dist/components/Modals.js +5 -2
  30. package/dist/components/NewComposition/ComboBox.js +8 -2
  31. package/dist/components/NewComposition/InputDragger.d.ts +1 -0
  32. package/dist/components/NewComposition/InputDragger.js +9 -6
  33. package/dist/components/NewComposition/RenameStaticFile.d.ts +4 -0
  34. package/dist/components/NewComposition/RenameStaticFile.js +118 -0
  35. package/dist/components/OptionsPanel.js +5 -1
  36. package/dist/components/OutlineToggle.d.ts +2 -0
  37. package/dist/components/OutlineToggle.js +20 -0
  38. package/dist/components/Preview.d.ts +0 -2
  39. package/dist/components/Preview.js +23 -33
  40. package/dist/components/PreviewToolbar.js +19 -6
  41. package/dist/components/RenderButton.js +8 -2
  42. package/dist/components/RenderPreview.js +2 -2
  43. package/dist/components/SelectedOutlineOverlay.d.ts +29 -3
  44. package/dist/components/SelectedOutlineOverlay.js +259 -80
  45. package/dist/components/ShowOutlinesProvider.d.ts +4 -0
  46. package/dist/components/ShowOutlinesProvider.js +24 -0
  47. package/dist/components/SizeSelector.js +3 -3
  48. package/dist/components/Splitter/SplitterHandle.js +2 -0
  49. package/dist/components/StaticFilePreview.js +2 -2
  50. package/dist/components/Timeline/KeyframeSettingsModal.d.ts +15 -0
  51. package/dist/components/Timeline/KeyframeSettingsModal.js +150 -0
  52. package/dist/components/Timeline/SequencePropsObserver.js +3 -3
  53. package/dist/components/Timeline/Timeline.js +3 -13
  54. package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +26 -3
  55. package/dist/components/Timeline/TimelineClipboardKeybindings.js +242 -25
  56. package/dist/components/Timeline/TimelineDeleteKeybindings.js +23 -11
  57. package/dist/components/Timeline/TimelineEffectItem.js +8 -7
  58. package/dist/components/Timeline/TimelineEffectPropItem.js +69 -19
  59. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +6 -1
  60. package/dist/components/Timeline/TimelineExpandedSection.js +5 -5
  61. package/dist/components/Timeline/TimelineKeyframeControls.js +13 -23
  62. package/dist/components/Timeline/TimelineKeyframeDiamond.js +24 -22
  63. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.d.ts +6 -0
  64. package/dist/components/Timeline/TimelineKeyframeDiamondIcon.js +14 -0
  65. package/dist/components/Timeline/TimelineKeyframeDragState.d.ts +17 -0
  66. package/dist/components/Timeline/TimelineKeyframeDragState.js +39 -0
  67. package/dist/components/Timeline/TimelineKeyframeEasingLine.d.ts +9 -0
  68. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +120 -0
  69. package/dist/components/Timeline/TimelineKeyframedValue.js +1 -1
  70. package/dist/components/Timeline/TimelineList.js +2 -2
  71. package/dist/components/Timeline/TimelineMediaInfo.d.ts +0 -13
  72. package/dist/components/Timeline/TimelineMediaInfo.js +8 -73
  73. package/dist/components/Timeline/TimelineNumberField.js +15 -7
  74. package/dist/components/Timeline/TimelineRotationField.js +17 -11
  75. package/dist/components/Timeline/TimelineScaleField.js +17 -13
  76. package/dist/components/Timeline/TimelineSelection.d.ts +15 -0
  77. package/dist/components/Timeline/TimelineSelection.js +26 -1
  78. package/dist/components/Timeline/TimelineSequence.js +6 -6
  79. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  80. package/dist/components/Timeline/TimelineSequenceItem.js +297 -36
  81. package/dist/components/Timeline/TimelineSequencePropItem.js +113 -48
  82. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +5 -5
  83. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +69 -70
  84. package/dist/components/Timeline/TimelineTranslateField.js +24 -19
  85. package/dist/components/Timeline/TimelineUvCoordinateField.js +18 -12
  86. package/dist/components/Timeline/apply-effect-response-to-prop-statuses.d.ts +5 -0
  87. package/dist/components/Timeline/apply-effect-response-to-prop-statuses.js +19 -0
  88. package/dist/components/Timeline/call-add-keyframe.d.ts +5 -5
  89. package/dist/components/Timeline/call-add-keyframe.js +6 -4
  90. package/dist/components/Timeline/call-delete-keyframe.d.ts +7 -7
  91. package/dist/components/Timeline/call-delete-keyframe.js +7 -7
  92. package/dist/components/Timeline/call-move-keyframe.d.ts +19 -0
  93. package/dist/components/Timeline/call-move-keyframe.js +71 -0
  94. package/dist/components/Timeline/call-update-keyframe-settings.d.ts +22 -0
  95. package/dist/components/Timeline/call-update-keyframe-settings.js +52 -0
  96. package/dist/components/Timeline/delete-selected-keyframe.d.ts +5 -5
  97. package/dist/components/Timeline/delete-selected-keyframe.js +5 -5
  98. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +10 -7
  99. package/dist/components/Timeline/delete-selected-timeline-item.js +37 -23
  100. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +4 -2
  101. package/dist/components/Timeline/duplicate-selected-timeline-item.js +39 -34
  102. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.d.ts +8 -0
  103. package/dist/components/Timeline/get-bounded-keyframe-drag-delta.js +12 -0
  104. package/dist/components/Timeline/get-keyframe-navigation.d.ts +2 -2
  105. package/dist/components/Timeline/get-keyframe-navigation.js +14 -6
  106. package/dist/components/Timeline/get-node-keyframes.d.ts +3 -3
  107. package/dist/components/Timeline/get-node-keyframes.js +4 -4
  108. package/dist/components/Timeline/get-timeline-easing-segments.d.ts +9 -0
  109. package/dist/components/Timeline/get-timeline-easing-segments.js +19 -0
  110. package/dist/components/Timeline/reset-selected-timeline-props.d.ts +7 -7
  111. package/dist/components/Timeline/reset-selected-timeline-props.js +13 -12
  112. package/dist/components/Timeline/save-effect-prop.d.ts +16 -5
  113. package/dist/components/Timeline/save-effect-prop.js +37 -19
  114. package/dist/components/Timeline/save-prop-queue.d.ts +4 -3
  115. package/dist/components/Timeline/save-prop-queue.js +6 -3
  116. package/dist/components/Timeline/save-sequence-prop.d.ts +5 -10
  117. package/dist/components/Timeline/save-sequence-prop.js +35 -32
  118. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +3 -0
  119. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +7 -0
  120. package/dist/components/Timeline/timeline-asset-link.d.ts +13 -0
  121. package/dist/components/Timeline/timeline-asset-link.js +37 -0
  122. package/dist/components/Timeline/timeline-field-utils.d.ts +10 -0
  123. package/dist/components/Timeline/timeline-field-utils.js +26 -5
  124. package/dist/components/Timeline/timeline-translate-utils.d.ts +1 -1
  125. package/dist/components/Timeline/timeline-translate-utils.js +6 -4
  126. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +7 -7
  127. package/dist/components/Timeline/use-sequence-props-subscription.js +3 -3
  128. package/dist/components/Timeline/use-timeline-height.js +3 -3
  129. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +10 -0
  130. package/dist/components/Timeline/use-timeline-keyframe-drag.js +380 -0
  131. package/dist/components/import-assets.d.ts +31 -0
  132. package/dist/components/import-assets.js +216 -17
  133. package/dist/components/load-canvas-content-from-url.d.ts +1 -0
  134. package/dist/components/load-canvas-content-from-url.js +9 -3
  135. package/dist/components/use-select-asset.d.ts +1 -0
  136. package/dist/components/use-select-asset.js +30 -0
  137. package/dist/error-overlay/error-origin.d.ts +3 -0
  138. package/dist/error-overlay/error-origin.js +42 -0
  139. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +6 -2
  140. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +38 -0
  141. package/dist/error-overlay/remotion-overlay/ShortcutHint.js +1 -1
  142. package/dist/error-overlay/remotion-overlay/log-studio-error.d.ts +3 -0
  143. package/dist/error-overlay/remotion-overlay/log-studio-error.js +27 -0
  144. package/dist/esm/{chunk-48grt472.js → chunk-xjvc8qen.js} +21838 -18862
  145. package/dist/esm/internals.mjs +21838 -18862
  146. package/dist/esm/previewEntry.mjs +21127 -18127
  147. package/dist/esm/renderEntry.mjs +1 -1
  148. package/dist/helpers/get-asset-metadata.js +2 -2
  149. package/dist/helpers/get-preview-file-type.d.ts +2 -0
  150. package/dist/helpers/get-preview-file-type.js +33 -0
  151. package/dist/helpers/install-required-package.d.ts +1 -0
  152. package/dist/helpers/install-required-package.js +39 -0
  153. package/dist/helpers/remote-asset-drag.d.ts +4 -0
  154. package/dist/helpers/remote-asset-drag.js +73 -0
  155. package/dist/helpers/timeline-layout.d.ts +6 -6
  156. package/dist/helpers/timeline-layout.js +5 -5
  157. package/dist/helpers/use-asset-drag-events.d.ts +5 -2
  158. package/dist/helpers/use-asset-drag-events.js +13 -2
  159. package/dist/hot-middleware-client/client.js +6 -0
  160. package/dist/state/editor-outlines.d.ts +8 -0
  161. package/dist/state/editor-outlines.js +18 -0
  162. package/dist/state/modals.d.ts +16 -2
  163. package/package.json +10 -10
  164. package/dist/helpers/detect-file-type.d.ts +0 -69
  165. package/dist/helpers/detect-file-type.js +0 -278
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfirmationDialog = exports.useConfirmationDialog = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
7
+ const modals_1 = require("../state/modals");
8
+ const Button_1 = require("./Button");
9
+ const layout_1 = require("./layout");
10
+ const ModalButton_1 = require("./ModalButton");
11
+ const ModalContainer_1 = require("./ModalContainer");
12
+ const ModalFooter_1 = require("./ModalFooter");
13
+ const ModalHeader_1 = require("./ModalHeader");
14
+ const content = {
15
+ padding: 16,
16
+ fontSize: 14,
17
+ flex: 1,
18
+ minWidth: 420,
19
+ maxWidth: 560,
20
+ lineHeight: 1.4,
21
+ };
22
+ const useConfirmationDialog = () => {
23
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
24
+ return (0, react_1.useCallback)((options) => {
25
+ return new Promise((resolve) => {
26
+ var _a, _b;
27
+ let settled = false;
28
+ const settle = (result) => {
29
+ if (settled) {
30
+ return;
31
+ }
32
+ settled = true;
33
+ resolve(result);
34
+ };
35
+ setSelectedModal({
36
+ type: 'confirmation-dialog',
37
+ id: String(Math.random()),
38
+ title: options.title,
39
+ message: options.message,
40
+ confirmLabel: (_a = options.confirmLabel) !== null && _a !== void 0 ? _a : 'Continue',
41
+ cancelLabel: (_b = options.cancelLabel) !== null && _b !== void 0 ? _b : 'Cancel',
42
+ onConfirm: () => settle(true),
43
+ onCancel: () => settle(false),
44
+ });
45
+ });
46
+ }, [setSelectedModal]);
47
+ };
48
+ exports.useConfirmationDialog = useConfirmationDialog;
49
+ const ConfirmationDialog = ({ state }) => {
50
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
51
+ const settledRef = (0, react_1.useRef)(false);
52
+ const closeCurrentModal = (0, react_1.useCallback)(() => {
53
+ setSelectedModal((modal) => (modal === null || modal === void 0 ? void 0 : modal.type) === 'confirmation-dialog' && modal.id === state.id
54
+ ? null
55
+ : modal);
56
+ }, [setSelectedModal, state.id]);
57
+ const settle = (0, react_1.useCallback)((confirmed) => {
58
+ if (settledRef.current) {
59
+ return;
60
+ }
61
+ settledRef.current = true;
62
+ closeCurrentModal();
63
+ if (confirmed) {
64
+ state.onConfirm();
65
+ }
66
+ else {
67
+ state.onCancel();
68
+ }
69
+ }, [closeCurrentModal, state]);
70
+ (0, react_1.useEffect)(() => {
71
+ return () => {
72
+ if (settledRef.current) {
73
+ return;
74
+ }
75
+ settledRef.current = true;
76
+ state.onCancel();
77
+ };
78
+ }, [state]);
79
+ const onCancel = (0, react_1.useCallback)(() => {
80
+ settle(false);
81
+ }, [settle]);
82
+ const onConfirm = (0, react_1.useCallback)(() => {
83
+ settle(true);
84
+ }, [settle]);
85
+ const onSubmit = (0, react_1.useCallback)((e) => {
86
+ e.preventDefault();
87
+ onConfirm();
88
+ }, [onConfirm]);
89
+ const cancelStyle = (0, react_1.useMemo)(() => {
90
+ return {
91
+ minWidth: 90,
92
+ };
93
+ }, []);
94
+ return (jsx_runtime_1.jsxs(ModalContainer_1.ModalContainer, { onOutsideClick: onCancel, onEscape: onCancel, children: [
95
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: state.title, onClose: onCancel }), jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [
96
+ jsx_runtime_1.jsx("div", { style: content, children: state.message }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", children: [
97
+ jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(Button_1.Button, { onClick: onCancel, style: cancelStyle, children: state.cancelLabel }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsxs(ModalButton_1.ModalButton, { onClick: onConfirm, autoFocus: true, children: [state.confirmLabel, jsx_runtime_1.jsx(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: false })
98
+ ] })
99
+ ] }) })
100
+ ] })
101
+ ] }));
102
+ };
103
+ exports.ConfirmationDialog = ConfirmationDialog;
@@ -1,12 +1,20 @@
1
1
  import React from 'react';
2
2
  import type { ComboboxValue } from './NewComposition/ComboBox';
3
+ type ContextMenuOpenHandler = () => false | void;
4
+ type ContextMenuTargetOpenResult = false | void | readonly ComboboxValue[];
5
+ type ContextMenuTargetOpenHandler = (event: MouseEvent) => ContextMenuTargetOpenResult | Promise<ContextMenuTargetOpenResult>;
3
6
  type ContextMenuProps = {
4
7
  readonly children: React.ReactNode;
5
8
  readonly values: ComboboxValue[];
6
- readonly onOpen: (() => void) | null;
9
+ readonly onOpen: ContextMenuOpenHandler | null;
7
10
  readonly style?: React.CSSProperties;
8
11
  readonly className?: string;
9
12
  readonly onPointerDown?: React.PointerEventHandler<HTMLDivElement>;
10
13
  };
11
14
  export declare const ContextMenu: React.ForwardRefExoticComponent<ContextMenuProps & React.RefAttributes<HTMLDivElement>>;
15
+ export declare const ContextMenuForTarget: React.FC<{
16
+ readonly triggerRef: React.RefObject<HTMLElement | SVGElement | null>;
17
+ readonly values: ComboboxValue[];
18
+ readonly onOpen: ContextMenuTargetOpenHandler | null;
19
+ }>;
12
20
  export {};
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.ContextMenu = void 0;
39
+ exports.ContextMenuForTarget = exports.ContextMenu = void 0;
40
40
  const jsx_runtime_1 = require("react/jsx-runtime");
41
41
  const player_1 = require("@remotion/player");
42
42
  const react_1 = __importStar(require("react"));
@@ -47,8 +47,8 @@ const z_index_1 = require("../state/z-index");
47
47
  const portals_1 = require("./Menu/portals");
48
48
  const styles_1 = require("./Menu/styles");
49
49
  const MenuContent_1 = require("./NewComposition/MenuContent");
50
- const ContextMenuPortal = ({ containerRef, currentZIndex, onHide, opened, values }) => {
51
- const size = player_1.PlayerInternals.useElementSize(containerRef, {
50
+ const ContextMenuPortal = ({ sizeSource, currentZIndex, onHide, opened, values }) => {
51
+ const size = player_1.PlayerInternals.useElementSize(sizeSource, {
52
52
  triggerOnWindowResize: true,
53
53
  shouldApplyCssTransforms: true,
54
54
  });
@@ -134,7 +134,9 @@ exports.ContextMenu = react_1.default.forwardRef(({ children, values, onOpen, st
134
134
  const onClick = (e) => {
135
135
  e.preventDefault();
136
136
  e.stopPropagation();
137
- onOpen === null || onOpen === void 0 ? void 0 : onOpen();
137
+ if ((onOpen === null || onOpen === void 0 ? void 0 : onOpen()) === false) {
138
+ return false;
139
+ }
138
140
  setOpened({ type: 'open', left: e.clientX, top: e.clientY });
139
141
  return false;
140
142
  };
@@ -147,6 +149,48 @@ exports.ContextMenu = react_1.default.forwardRef(({ children, values, onOpen, st
147
149
  setOpened({ type: 'not-open' });
148
150
  }, []);
149
151
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
150
- 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, { containerRef: ref, currentZIndex: currentZIndex, onHide: onHide, opened: opened, values: values })) : null] }));
152
+ 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, { sizeSource: ref, currentZIndex: currentZIndex, onHide: onHide, opened: opened, values: values })) : null] }));
151
153
  });
152
154
  exports.ContextMenu.displayName = 'ContextMenu';
155
+ const ContextMenuForTarget = ({ triggerRef, values, onOpen }) => {
156
+ const [opened, setOpened] = (0, react_1.useState)({ type: 'not-open' });
157
+ const [openedValues, setOpenedValues] = (0, react_1.useState)(values);
158
+ const [body, setBody] = (0, react_1.useState)(null);
159
+ const { currentZIndex } = (0, z_index_1.useZIndex)();
160
+ (0, react_1.useEffect)(() => {
161
+ // Access document.body after mount so importing this component stays safe
162
+ // in DOM-less test environments.
163
+ setBody(document.body);
164
+ }, []);
165
+ (0, react_1.useEffect)(() => {
166
+ const { current } = triggerRef;
167
+ if (!current) {
168
+ return;
169
+ }
170
+ const onClick = async (event) => {
171
+ const e = event;
172
+ e.preventDefault();
173
+ e.stopPropagation();
174
+ const result = await (onOpen === null || onOpen === void 0 ? void 0 : onOpen(e));
175
+ if (result === false) {
176
+ return false;
177
+ }
178
+ const nextValues = Array.isArray(result) ? result : values;
179
+ if (nextValues.length === 0) {
180
+ return false;
181
+ }
182
+ setOpenedValues(nextValues);
183
+ setOpened({ type: 'open', left: e.clientX, top: e.clientY });
184
+ return false;
185
+ };
186
+ current.addEventListener('contextmenu', onClick);
187
+ return () => {
188
+ current.removeEventListener('contextmenu', onClick);
189
+ };
190
+ }, [onOpen, triggerRef, values]);
191
+ const onHide = (0, react_1.useCallback)(() => {
192
+ setOpened({ type: 'not-open' });
193
+ }, []);
194
+ return opened.type === 'open' ? (jsx_runtime_1.jsx(ContextMenuPortal, { sizeSource: body, currentZIndex: currentZIndex, onHide: onHide, opened: opened, values: [...openedValues] })) : null;
195
+ };
196
+ exports.ContextMenuForTarget = ContextMenuForTarget;
@@ -1,3 +1,4 @@
1
1
  import React from 'react';
2
2
  export declare const CURRENT_ASSET_HEIGHT = 80;
3
+ export declare const getCurrentAssetMetadataSource: (assetName: string | null) => string | null;
3
4
  export declare const CurrentAsset: React.FC;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CurrentAsset = exports.CURRENT_ASSET_HEIGHT = void 0;
3
+ exports.CurrentAsset = exports.getCurrentAssetMetadataSource = exports.CURRENT_ASSET_HEIGHT = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const colors_1 = require("../helpers/colors");
9
9
  const format_media_duration_1 = require("../helpers/format-media-duration");
10
+ const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
10
11
  const use_media_metadata_1 = require("../helpers/use-media-metadata");
11
12
  const use_static_files_1 = require("./use-static-files");
12
13
  exports.CURRENT_ASSET_HEIGHT = 80;
@@ -38,6 +39,16 @@ const row = {
38
39
  lineHeight: '18px',
39
40
  backgroundColor: colors_1.BACKGROUND,
40
41
  };
42
+ const getCurrentAssetMetadataSource = (assetName) => {
43
+ if (!assetName) {
44
+ return null;
45
+ }
46
+ const fileType = (0, get_preview_file_type_1.getPreviewFileType)(assetName);
47
+ return fileType === 'audio' || fileType === 'video'
48
+ ? (0, remotion_1.staticFile)(assetName)
49
+ : null;
50
+ };
51
+ exports.getCurrentAssetMetadataSource = getCurrentAssetMetadataSource;
41
52
  const CurrentAsset = () => {
42
53
  var _a;
43
54
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
@@ -51,7 +62,7 @@ const CurrentAsset = () => {
51
62
  const file = staticFiles.find((f) => f.name === assetName);
52
63
  return (_a = file === null || file === void 0 ? void 0 : file.sizeInBytes) !== null && _a !== void 0 ? _a : null;
53
64
  }, [assetName, staticFiles]);
54
- const src = assetName ? (0, remotion_1.staticFile)(assetName) : null;
65
+ const src = (0, exports.getCurrentAssetMetadataSource)(assetName);
55
66
  const mediaMetadata = (0, use_media_metadata_1.useMediaMetadata)(src);
56
67
  if (!assetName) {
57
68
  return jsx_runtime_1.jsx("div", { style: container });
@@ -9,8 +9,10 @@ const MenuToolbar_1 = require("./MenuToolbar");
9
9
  const SplitterContainer_1 = require("./Splitter/SplitterContainer");
10
10
  const SplitterElement_1 = require("./Splitter/SplitterElement");
11
11
  const SplitterHandle_1 = require("./Splitter/SplitterHandle");
12
+ const should_clear_selection_on_pointer_down_1 = require("./Timeline/should-clear-selection-on-pointer-down");
12
13
  const Timeline_1 = require("./Timeline/Timeline");
13
14
  const TimelineEmptyState_1 = require("./Timeline/TimelineEmptyState");
15
+ const TimelineKeyframeDragState_1 = require("./Timeline/TimelineKeyframeDragState");
14
16
  const TimelineSelection_1 = require("./Timeline/TimelineSelection");
15
17
  const noop = () => undefined;
16
18
  const container = {
@@ -19,13 +21,24 @@ const container = {
19
21
  flex: 1,
20
22
  height: 0,
21
23
  };
24
+ const StudioClearSelectionArea = ({ children }) => {
25
+ const { clearSelection } = (0, TimelineSelection_1.useTimelineSelection)();
26
+ const onPointerDown = (0, react_1.useCallback)((e) => {
27
+ if (!(0, should_clear_selection_on_pointer_down_1.shouldClearSelectionOnPointerDown)(e)) {
28
+ return;
29
+ }
30
+ clearSelection();
31
+ }, [clearSelection]);
32
+ return (jsx_runtime_1.jsx("div", { style: container, onPointerDown: onPointerDown, children: children }));
33
+ };
22
34
  const EditorContent = ({ readOnlyStudio, children }) => {
23
35
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
24
36
  const showTimeline = canvasContent !== null && canvasContent.type === 'composition';
25
37
  const content = (jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "horizontal", id: "top-to-bottom", maxFlex: 0.9, minFlex: 0.2, defaultFlex: 0.75, children: [
26
38
  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, {}) })
27
39
  ] }));
28
- return (jsx_runtime_1.jsxs("div", { style: container, children: [
29
- jsx_runtime_1.jsx(InitialCompositionLoader_1.InitialCompositionLoader, {}), jsx_runtime_1.jsx(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), showTimeline ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionProvider, { children: content })) : (content)] }));
40
+ return (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionProvider, { children: jsx_runtime_1.jsxs(StudioClearSelectionArea, { children: [
41
+ jsx_runtime_1.jsx(InitialCompositionLoader_1.InitialCompositionLoader, {}), jsx_runtime_1.jsx(MenuToolbar_1.MenuToolbar, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(TimelineKeyframeDragState_1.TimelineKeyframeDragStateProvider, { children: content })
42
+ ] }) }));
30
43
  };
31
44
  exports.EditorContent = EditorContent;
@@ -19,13 +19,14 @@ const ClientRenderQueueProcessor_1 = require("./RenderQueue/ClientRenderQueuePro
19
19
  const context_1 = require("./RenderQueue/context");
20
20
  const SetTimelineInOutProvider_1 = require("./SetTimelineInOutProvider");
21
21
  const ShowGuidesProvider_1 = require("./ShowGuidesProvider");
22
+ const ShowOutlinesProvider_1 = require("./ShowOutlinesProvider");
22
23
  const ShowRulersProvider_1 = require("./ShowRulersProvider");
23
24
  const VisualControlsUndoSync_1 = require("./VisualControls/VisualControlsUndoSync");
24
25
  const ZoomGesturesProvider_1 = require("./ZoomGesturesProvider");
25
26
  const EditorContexts = ({ children, readOnlyStudio }) => {
26
27
  return (jsx_runtime_1.jsx(get_zod_if_possible_1.ZodProvider, { children: jsx_runtime_1.jsx(VisualControls_1.VisualControlsProvider, { children: jsx_runtime_1.jsxs(client_id_1.PreviewServerConnection, { readOnlyStudio: readOnlyStudio, children: [
27
28
  jsx_runtime_1.jsx(VisualControlsUndoSync_1.VisualControlsUndoSync, {}), jsx_runtime_1.jsxs(context_1.RenderQueueContextProvider, { children: [
28
- jsx_runtime_1.jsx(ClientRenderQueueProcessor_1.ClientRenderQueueProcessor, {}), jsx_runtime_1.jsx(keybindings_1.KeybindingContextProvider, { children: jsx_runtime_1.jsx(CheckerboardProvider_1.CheckerboardProvider, { children: jsx_runtime_1.jsx(ZoomGesturesProvider_1.ZoomGesturesProvider, { children: jsx_runtime_1.jsx(ShowRulersProvider_1.ShowRulersProvider, { children: jsx_runtime_1.jsx(ShowGuidesProvider_1.ShowGuidesProvider, { children: jsx_runtime_1.jsx(preview_size_1.PreviewSizeProvider, { children: jsx_runtime_1.jsx(ModalsProvider_1.ModalsProvider, { children: jsx_runtime_1.jsx(MediaVolumeProvider_1.MediaVolumeProvider, { children: jsx_runtime_1.jsx(player_1.PlayerInternals.PlayerEmitterProvider, { currentPlaybackRate: null, children: jsx_runtime_1.jsx(sidebar_1.SidebarContextProvider, { children: jsx_runtime_1.jsx(folders_1.FolderContextProvider, { children: jsx_runtime_1.jsx(highest_z_index_1.HighestZIndexProvider, { children: jsx_runtime_1.jsx(SetTimelineInOutProvider_1.SetTimelineInOutProvider, { children: jsx_runtime_1.jsx(ExpandedTracksProvider_1.ExpandedTracksProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }) }) })
29
+ jsx_runtime_1.jsx(ClientRenderQueueProcessor_1.ClientRenderQueueProcessor, {}), jsx_runtime_1.jsx(keybindings_1.KeybindingContextProvider, { children: jsx_runtime_1.jsx(CheckerboardProvider_1.CheckerboardProvider, { children: jsx_runtime_1.jsx(ZoomGesturesProvider_1.ZoomGesturesProvider, { children: jsx_runtime_1.jsx(ShowRulersProvider_1.ShowRulersProvider, { children: jsx_runtime_1.jsx(ShowGuidesProvider_1.ShowGuidesProvider, { children: jsx_runtime_1.jsx(ShowOutlinesProvider_1.ShowOutlinesProvider, { children: jsx_runtime_1.jsx(preview_size_1.PreviewSizeProvider, { children: jsx_runtime_1.jsx(ModalsProvider_1.ModalsProvider, { children: jsx_runtime_1.jsx(MediaVolumeProvider_1.MediaVolumeProvider, { children: jsx_runtime_1.jsx(player_1.PlayerInternals.PlayerEmitterProvider, { currentPlaybackRate: null, children: jsx_runtime_1.jsx(sidebar_1.SidebarContextProvider, { children: jsx_runtime_1.jsx(folders_1.FolderContextProvider, { children: jsx_runtime_1.jsx(highest_z_index_1.HighestZIndexProvider, { children: jsx_runtime_1.jsx(SetTimelineInOutProvider_1.SetTimelineInOutProvider, { children: jsx_runtime_1.jsx(ExpandedTracksProvider_1.ExpandedTracksProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }) }) }) })
29
30
  ] })
30
31
  ] }) }) }));
31
32
  };
@@ -67,6 +67,8 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
67
67
  return;
68
68
  }
69
69
  e.preventDefault();
70
+ // Prevent deselection of currently selected items
71
+ e.stopPropagation();
70
72
  shouldCreateGuideRef.current = true;
71
73
  (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
72
74
  const guideId = makeGuideId();
@@ -1,7 +1,3 @@
1
- export declare const explorerSidebarTabs: import("react").RefObject<{
2
- selectAssetsPanel: () => void;
3
- selectCompositionPanel: () => void;
4
- } | null>;
5
1
  export declare const ExplorerPanel: React.FC<{
6
2
  readOnlyStudio: boolean;
7
3
  }>;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExplorerPanel = exports.explorerSidebarTabs = void 0;
3
+ exports.ExplorerPanel = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../helpers/colors");
7
7
  const AssetSelector_1 = require("./AssetSelector");
8
8
  const CompositionSelector_1 = require("./CompositionSelector");
9
9
  const CompSelectorRef_1 = require("./CompSelectorRef");
10
+ const ExplorerPanelRef_1 = require("./ExplorerPanelRef");
10
11
  const Tabs_1 = require("./Tabs");
11
12
  const container = {
12
13
  height: '100%',
@@ -30,7 +31,6 @@ const tabsContainer = {
30
31
  const persistSelectedOptionsSidebarPanel = (panel) => {
31
32
  localStorage.setItem(localStorageKey, panel);
32
33
  };
33
- exports.explorerSidebarTabs = (0, react_1.createRef)();
34
34
  const ExplorerPanel = ({ readOnlyStudio }) => {
35
35
  const [panel, setPanel] = (0, react_1.useState)(() => getSelectedPanel());
36
36
  const onCompositionsSelected = (0, react_1.useCallback)(() => {
@@ -41,7 +41,7 @@ const ExplorerPanel = ({ readOnlyStudio }) => {
41
41
  setPanel('assets');
42
42
  persistSelectedOptionsSidebarPanel('assets');
43
43
  }, []);
44
- (0, react_1.useImperativeHandle)(exports.explorerSidebarTabs, () => {
44
+ (0, react_1.useImperativeHandle)(ExplorerPanelRef_1.explorerSidebarTabs, () => {
45
45
  return {
46
46
  selectAssetsPanel: () => {
47
47
  setPanel('assets');
@@ -53,7 +53,11 @@ const ExplorerPanel = ({ readOnlyStudio }) => {
53
53
  },
54
54
  };
55
55
  }, []);
56
- return (jsx_runtime_1.jsx(CompSelectorRef_1.CompSelectorRef, { children: jsx_runtime_1.jsxs("div", { style: container, className: "css-reset", children: [
56
+ const onPointerDown = (0, react_1.useCallback)((e) => {
57
+ // Prevent deselection of currently selected items
58
+ e.stopPropagation();
59
+ }, []);
60
+ return (jsx_runtime_1.jsx(CompSelectorRef_1.CompSelectorRef, { children: jsx_runtime_1.jsxs("div", { style: container, className: "css-reset", onPointerDown: onPointerDown, children: [
57
61
  jsx_runtime_1.jsx("div", { style: tabsContainer, children: jsx_runtime_1.jsxs(Tabs_1.Tabs, { children: [
58
62
  jsx_runtime_1.jsx(Tabs_1.Tab, { selected: panel === 'compositions', onClick: onCompositionsSelected, children: "Compositions" }), jsx_runtime_1.jsx(Tabs_1.Tab, { selected: panel === 'assets', onClick: onAssetsSelected, children: "Assets" })
59
63
  ] }) }), panel === 'compositions' ? (jsx_runtime_1.jsx(CompositionSelector_1.CompositionSelector, {})) : (jsx_runtime_1.jsx(AssetSelector_1.AssetSelector, { readOnlyStudio: readOnlyStudio }))] }) }));
@@ -0,0 +1,4 @@
1
+ export declare const explorerSidebarTabs: import("react").RefObject<{
2
+ selectAssetsPanel: () => void;
3
+ selectCompositionPanel: () => void;
4
+ } | null>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.explorerSidebarTabs = void 0;
4
+ const react_1 = require("react");
5
+ exports.explorerSidebarTabs = (0, react_1.createRef)();
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { AssetMetadata } from '../helpers/get-asset-metadata';
3
- import type { AssetFileType } from './Preview';
3
+ import type { AssetFileType } from '../helpers/get-preview-file-type';
4
4
  export declare const FilePreview: React.FC<{
5
5
  readonly src: string;
6
6
  readonly fileType: AssetFileType;
@@ -1,4 +1,3 @@
1
1
  import type React from 'react';
2
- export declare const useSelectAsset: () => (asset: string) => void;
3
2
  export declare const useSelectComposition: () => (c: import("remotion").AnyComposition, push: boolean) => void;
4
3
  export declare const InitialCompositionLoader: React.FC;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InitialCompositionLoader = exports.useSelectComposition = exports.useSelectAsset = void 0;
3
+ exports.InitialCompositionLoader = exports.useSelectComposition = void 0;
4
4
  const react_1 = require("react");
5
5
  const remotion_1 = require("remotion");
6
6
  const create_folder_tree_1 = require("../helpers/create-folder-tree");
@@ -9,32 +9,10 @@ const persist_open_folders_1 = require("../helpers/persist-open-folders");
9
9
  const url_state_1 = require("../helpers/url-state");
10
10
  const folders_1 = require("../state/folders");
11
11
  const sidebar_1 = require("../state/sidebar");
12
- const ExplorerPanel_1 = require("./ExplorerPanel");
12
+ const ExplorerPanelRef_1 = require("./ExplorerPanelRef");
13
13
  const load_canvas_content_from_url_1 = require("./load-canvas-content-from-url");
14
+ const use_select_asset_1 = require("./use-select-asset");
14
15
  const use_static_files_1 = require("./use-static-files");
15
- const useSelectAsset = () => {
16
- const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
17
- const { setAssetFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
18
- return (0, react_1.useCallback)((asset) => {
19
- var _a;
20
- setCanvasContent({ type: 'asset', asset });
21
- (_a = ExplorerPanel_1.explorerSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectAssetsPanel();
22
- setAssetFoldersExpanded((ex) => {
23
- const split = asset.split('/');
24
- const keysToExpand = split.map((_, i) => {
25
- return split.slice(0, i).join('/');
26
- });
27
- const newState = {
28
- ...ex,
29
- };
30
- for (const key of keysToExpand) {
31
- newState[key] = true;
32
- }
33
- return newState;
34
- });
35
- }, [setAssetFoldersExpanded, setCanvasContent]);
36
- };
37
- exports.useSelectAsset = useSelectAsset;
38
16
  const useSelectComposition = () => {
39
17
  const { setCompositionFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
40
18
  const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
@@ -45,7 +23,7 @@ const useSelectComposition = () => {
45
23
  if (push) {
46
24
  (0, url_state_1.pushUrl)(`/${c.id}`);
47
25
  }
48
- (_a = ExplorerPanel_1.explorerSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectCompositionPanel();
26
+ (_a = ExplorerPanelRef_1.explorerSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectCompositionPanel();
49
27
  setCanvasContent({ type: 'composition', compositionId: c.id });
50
28
  const { folderName, parentFolderName } = c;
51
29
  if (folderName !== null) {
@@ -76,7 +54,7 @@ const InitialCompositionLoader = () => {
76
54
  const { compositions, canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
77
55
  const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
78
56
  const selectComposition = (0, exports.useSelectComposition)();
79
- const selectAsset = (0, exports.useSelectAsset)();
57
+ const selectAsset = (0, use_select_asset_1.useSelectAsset)();
80
58
  const staticFiles = (0, use_static_files_1.useStaticFiles)();
81
59
  (0, react_1.useEffect)(() => {
82
60
  const canvasContentFromUrl = (0, load_canvas_content_from_url_1.deriveCanvasContentFromUrl)();
@@ -61,6 +61,8 @@ const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered
61
61
  setHovered(false);
62
62
  }, []);
63
63
  const onPointerDown = (0, react_1.useCallback)((e) => {
64
+ // Prevent deselection of currently selected items
65
+ e.stopPropagation();
64
66
  if (e.button !== 0) {
65
67
  return;
66
68
  }
@@ -73,6 +75,10 @@ const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered
73
75
  once: true,
74
76
  });
75
77
  }, [id, onItemQuit, onItemSelected]);
78
+ const onMenuPointerDown = (0, react_1.useCallback)((e) => {
79
+ // Prevent deselection of currently selected items
80
+ e.stopPropagation();
81
+ }, []);
76
82
  const onClick = (0, react_1.useCallback)((e) => {
77
83
  e.stopPropagation();
78
84
  const isKeyboardInitiated = e.detail === 0;
@@ -92,7 +98,7 @@ const MenuItem = ({ label: itemName, selected, id, onItemSelected, onItemHovered
92
98
  }, [size]);
93
99
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
94
100
  jsx_runtime_1.jsx("button", { ref: ref, role: "button", tabIndex: tabIndex, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, onPointerDown: onPointerDown, onClick: onClick, style: containerStyle, type: "button", className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, children: itemName }), portalStyle
95
- ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { className: "css-reset", style: outerStyle, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onItemQuit, onOutsideClick: onItemQuit, children: jsx_runtime_1.jsx("div", { style: portalStyle, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: onPreviousMenu, onPreviousMenu: onNextMenu, values: menu.items, onHide: onItemQuit, leaveLeftSpace: menu.leaveLeftPadding, preselectIndex: false, topItemCanBeUnselected: true, fixedHeight: null }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
101
+ ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { className: "css-reset", style: outerStyle, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onItemQuit, onOutsideClick: onItemQuit, children: jsx_runtime_1.jsx("div", { style: portalStyle, onPointerDown: onMenuPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: onPreviousMenu, onPreviousMenu: onNextMenu, values: menu.items, onHide: onItemQuit, leaveLeftSpace: menu.leaveLeftPadding, preselectIndex: false, topItemCanBeUnselected: true, fixedHeight: null }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
96
102
  : null] }));
97
103
  };
98
104
  exports.MenuItem = MenuItem;
@@ -18,7 +18,11 @@ const SubMenuComponent = ({ portalStyle, subMenuActivated, subMenu, onQuitFullMe
18
18
  onQuitFullMenu();
19
19
  }
20
20
  }, [mobileLayout, onQuitFullMenu, onQuitSubMenu]);
21
- return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onQuitFullMenu, onOutsideClick: onOutsideClick, children: jsx_runtime_1.jsx("div", { style: portalStyle, className: "css-reset", children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: onQuitSubMenu, values: subMenu.items, onHide: onQuitFullMenu, leaveLeftSpace: subMenu.leaveLeftSpace, preselectIndex: subMenuActivated === 'without-mouse' &&
21
+ const onPointerDown = (0, react_1.useCallback)((e) => {
22
+ // Prevent deselection of currently selected items
23
+ e.stopPropagation();
24
+ }, []);
25
+ return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: onQuitFullMenu, onOutsideClick: onOutsideClick, children: jsx_runtime_1.jsx("div", { style: portalStyle, className: "css-reset", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: onQuitSubMenu, values: subMenu.items, onHide: onQuitFullMenu, leaveLeftSpace: subMenu.leaveLeftSpace, preselectIndex: subMenuActivated === 'without-mouse' &&
22
26
  typeof subMenu.preselectIndex === 'number'
23
27
  ? subMenu.preselectIndex
24
28
  : false, topItemCanBeUnselected: false, fixedHeight: null }) }) }));
@@ -1,15 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPortal = exports.portals = void 0;
4
- exports.portals = [
5
- document.getElementById('menuportal-0'),
6
- document.getElementById('menuportal-1'),
7
- document.getElementById('menuportal-2'),
8
- document.getElementById('menuportal-3'),
9
- document.getElementById('menuportal-4'),
10
- document.getElementById('menuportal-5'),
4
+ const portalIds = [
5
+ 'menuportal-0',
6
+ 'menuportal-1',
7
+ 'menuportal-2',
8
+ 'menuportal-3',
9
+ 'menuportal-4',
10
+ 'menuportal-5',
11
11
  ];
12
+ exports.portals =
13
+ // This module is imported by Bun tests that run without a DOM.
14
+ typeof document === 'undefined'
15
+ ? []
16
+ : portalIds.map((id) => document.getElementById(id));
12
17
  const getPortal = (i) => {
13
- return exports.portals[i];
18
+ const portal = exports.portals[i];
19
+ if (!portal) {
20
+ throw new Error(`Expected menu portal ${i} to exist`);
21
+ }
22
+ return portal;
14
23
  };
15
24
  exports.getPortal = getPortal;
@@ -90,7 +90,11 @@ const MenuToolbar = ({ readOnlyStudio }) => {
90
90
  const onItemQuit = (0, react_1.useCallback)(() => {
91
91
  setSelected(null);
92
92
  }, [setSelected]);
93
- return (jsx_runtime_1.jsxs(layout_1.Row, { align: "center", className: "css-reset", style: row, children: [
93
+ const onPointerDown = (0, react_1.useCallback)((e) => {
94
+ // Prevent deselection of currently selected items
95
+ e.stopPropagation();
96
+ }, []);
97
+ return (jsx_runtime_1.jsxs(layout_1.Row, { align: "center", className: "css-reset", style: row, onPointerDown: onPointerDown, children: [
94
98
  jsx_runtime_1.jsxs("div", { style: fixedWidthLeft, children: [structure.map((s) => {
95
99
  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));
96
100
  }), readOnlyStudio ? null : jsx_runtime_1.jsx(UpdateCheck_1.UpdateCheck, {})] }), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsx(MenuBuildIndicator_1.MenuBuildIndicator, {}), jsx_runtime_1.jsx("div", { style: flex }), jsx_runtime_1.jsxs("div", { style: fixedWidthRight, children: [readOnlyStudio ? null : jsx_runtime_1.jsx(UndoRedoButtons_1.UndoRedoButtons, {}), jsx_runtime_1.jsx(SidebarCollapserControls_1.SidebarCollapserControls, {})
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModalContainer = exports.getMaxModalHeight = exports.getMaxModalWidth = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
5
6
  const colors_1 = require("../helpers/colors");
6
7
  const z_index_1 = require("../state/z-index");
7
8
  const padding = 20;
@@ -29,6 +30,10 @@ const panel = {
29
30
  margin: 'auto',
30
31
  };
31
32
  const ModalContainer = ({ children, onEscape, onOutsideClick, noZIndex }) => {
32
- return (jsx_runtime_1.jsx("div", { className: "css-reset", style: backgroundOverlay, role: "dialog", "aria-modal": "true", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { disabled: noZIndex, onOutsideClick: onOutsideClick, onEscape: onEscape, children: jsx_runtime_1.jsx("div", { style: panel, children: children }) }) }));
33
+ const onPointerDown = (0, react_1.useCallback)((e) => {
34
+ // Prevent deselection of currently selected items
35
+ e.stopPropagation();
36
+ }, []);
37
+ return (jsx_runtime_1.jsx("div", { className: "css-reset", style: backgroundOverlay, role: "dialog", "aria-modal": "true", onPointerDown: onPointerDown, children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { disabled: noZIndex, onOutsideClick: onOutsideClick, onEscape: onEscape, children: jsx_runtime_1.jsx("div", { style: panel, children: children }) }) }));
33
38
  };
34
39
  exports.ModalContainer = ModalContainer;