@remotion/studio 4.0.523 → 4.0.525

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 (182) hide show
  1. package/dist/components/ActionTooltip.d.ts +11 -0
  2. package/dist/components/ActionTooltip.js +153 -0
  3. package/dist/components/AppLaunchButton.js +2 -0
  4. package/dist/components/AssetSelectorModal.d.ts +6 -0
  5. package/dist/components/AssetSelectorModal.js +174 -0
  6. package/dist/components/Canvas.js +18 -3
  7. package/dist/components/CheckboardToggle.js +8 -10
  8. package/dist/components/ColorPicker/AlphaSlider.js +1 -1
  9. package/dist/components/ColorPicker/HueSlider.js +1 -1
  10. package/dist/components/ColorPicker/SaturationValueArea.js +1 -1
  11. package/dist/components/CompositionSelector.js +1 -0
  12. package/dist/components/CompositionSelectorItem.js +1 -0
  13. package/dist/components/EditorGuides/Guide.js +1 -1
  14. package/dist/components/ElementInstallConfirmation.js +35 -62
  15. package/dist/components/FullscreenToggle.js +5 -8
  16. package/dist/components/GlobalKeybindings.js +71 -0
  17. package/dist/components/InspectorLocationCopy.js +1 -1
  18. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  19. package/dist/components/InspectorOpenInEditor.js +18 -15
  20. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +6 -7
  21. package/dist/components/InspectorPanel/CompositionMetadata.js +1 -0
  22. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -0
  23. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +4 -12
  24. package/dist/components/InspectorSequenceSection.js +23 -14
  25. package/dist/components/LazySyntaxHighlightedSource.d.ts +4 -0
  26. package/dist/components/LazySyntaxHighlightedSource.js +43 -0
  27. package/dist/components/LoopToggle.js +9 -2
  28. package/dist/components/Menu/MenuItem.js +1 -2
  29. package/dist/components/MenuBuildIndicator.js +1 -1
  30. package/dist/components/MenuToolbar.js +6 -4
  31. package/dist/components/Modals.js +2 -1
  32. package/dist/components/MuteToggle.d.ts +1 -0
  33. package/dist/components/MuteToggle.js +17 -6
  34. package/dist/components/NewComposition/CodemodFooter.js +1 -0
  35. package/dist/components/NewComposition/DeleteComposition.js +42 -6
  36. package/dist/components/NewComposition/DeleteFolder.js +1 -0
  37. package/dist/components/NewComposition/DuplicateComposition.js +5 -0
  38. package/dist/components/NewComposition/InputDragger.js +2 -2
  39. package/dist/components/NewComposition/NewComposition.d.ts +1 -0
  40. package/dist/components/NewComposition/NewComposition.js +5 -4
  41. package/dist/components/NewComposition/NewFolder.js +31 -6
  42. package/dist/components/NewComposition/RenameComposition.js +3 -2
  43. package/dist/components/NewComposition/RenameFolder.js +3 -4
  44. package/dist/components/NewComposition/SlugPreview.d.ts +7 -0
  45. package/dist/components/NewComposition/SlugPreview.js +18 -0
  46. package/dist/components/NewComposition/duplicate-composition-api.d.ts +3 -2
  47. package/dist/components/NewComposition/duplicate-composition-api.js +9 -2
  48. package/dist/components/Notifications/NotificationCenter.d.ts +1 -0
  49. package/dist/components/Notifications/NotificationCenter.js +22 -1
  50. package/dist/components/OutlineToggle.js +17 -10
  51. package/dist/components/PlayPause.js +7 -1
  52. package/dist/components/PlaybackKeyboardShortcutsManager.d.ts +2 -0
  53. package/dist/components/PlaybackKeyboardShortcutsManager.js +36 -1
  54. package/dist/components/PlaybackRateSelector.js +2 -2
  55. package/dist/components/Preview.js +0 -3
  56. package/dist/components/PreviewToolbar.js +4 -7
  57. package/dist/components/PreviewToolbarOverflowButton.js +10 -3
  58. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  59. package/dist/components/RenderButton.js +40 -4
  60. package/dist/components/RenderModal/WebRenderModalBasic.js +1 -1
  61. package/dist/components/RenderModal/render-modals.js +3 -0
  62. package/dist/components/RenderQueue/CaptionQueueItem.js +2 -1
  63. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +2 -1
  64. package/dist/components/RenderQueue/RenderQueueDownloadItem.js +2 -1
  65. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +2 -1
  66. package/dist/components/RenderQueue/RenderQueueOpenInFolder.js +2 -1
  67. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +2 -1
  68. package/dist/components/RenderQueue/RenderQueueRepeat.js +2 -1
  69. package/dist/components/RenderQueue/VideoMattingQueueItem.js +2 -1
  70. package/dist/components/RenderQueue/actions.d.ts +2 -1
  71. package/dist/components/RenderQueue/actions.js +2 -1
  72. package/dist/components/RulersAndGuidesToggle.js +8 -1
  73. package/dist/components/SegmentedButton.d.ts +1 -0
  74. package/dist/components/SegmentedButton.js +9 -3
  75. package/dist/components/SelectedOutlineElement.js +16 -6
  76. package/dist/components/SelectedOutlinePolygon.js +4 -2
  77. package/dist/components/SettingsButton.js +8 -6
  78. package/dist/components/SettingsContext.d.ts +8 -0
  79. package/dist/components/SettingsContext.js +57 -2
  80. package/dist/components/SettingsModal.js +4 -1
  81. package/dist/components/SettingsModalFooter.js +1 -1
  82. package/dist/components/SidebarCollapserControls.js +13 -16
  83. package/dist/components/SizeSelector.js +2 -2
  84. package/dist/components/SkillsSettings.js +35 -4
  85. package/dist/components/SnappingToggle.js +7 -8
  86. package/dist/components/Splitter/SplitterHandle.js +1 -2
  87. package/dist/components/StudioSettings.js +32 -18
  88. package/dist/components/SyntaxHighlightedSource.d.ts +5 -0
  89. package/dist/components/{HighlightedElementSource.js → SyntaxHighlightedSource.js} +2 -2
  90. package/dist/components/Tabs/vertical.d.ts +1 -1
  91. package/dist/components/Tabs/vertical.js +16 -2
  92. package/dist/components/Timeline/EasingEditorModal.js +2 -2
  93. package/dist/components/Timeline/Timeline.js +47 -39
  94. package/dist/components/Timeline/TimelineAssetField.js +148 -9
  95. package/dist/components/Timeline/TimelineDragHandler.js +1 -2
  96. package/dist/components/Timeline/TimelineEffectItem.d.ts +1 -0
  97. package/dist/components/Timeline/TimelineEffectItem.js +2 -2
  98. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  99. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  100. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  101. package/dist/components/Timeline/TimelineInOutDragHandler.js +1 -2
  102. package/dist/components/Timeline/TimelineLayerChildren.js +12 -9
  103. package/dist/components/Timeline/TimelineSchemaField.js +8 -1
  104. package/dist/components/Timeline/TimelineSelection.d.ts +3 -1
  105. package/dist/components/Timeline/TimelineSelection.js +32 -5
  106. package/dist/components/Timeline/TimelineSequence.js +6 -6
  107. package/dist/components/Timeline/TimelineSequenceItem.js +12 -10
  108. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -12
  109. package/dist/components/Timeline/TimelineTranslateField.js +25 -12
  110. package/dist/components/Timeline/TimelineZoomControls.js +2 -1
  111. package/dist/components/Timeline/get-sequence-context-menu-items.js +22 -6
  112. package/dist/components/Timeline/timeline-field-display-utils.js +12 -7
  113. package/dist/components/Timeline/timeline-translate-utils.d.ts +17 -0
  114. package/dist/components/Timeline/timeline-translate-utils.js +53 -12
  115. package/dist/components/Timeline/use-open-sequence-in-apps.d.ts +2 -0
  116. package/dist/components/Timeline/use-open-sequence-in-apps.js +17 -0
  117. package/dist/components/Timeline/use-timeline-asset-drop.js +17 -3
  118. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  119. package/dist/components/TimelineCombobox.d.ts +1 -0
  120. package/dist/components/TimelineCombobox.js +9 -4
  121. package/dist/components/TimelineInOutToggle.js +8 -15
  122. package/dist/components/UndoRedoButtons.js +11 -0
  123. package/dist/components/composition-menu-items.js +56 -2
  124. package/dist/components/folder-menu-items.js +44 -0
  125. package/dist/components/get-open-in-menu-items.js +1 -1
  126. package/dist/components/handle-drop.js +3 -2
  127. package/dist/components/import-assets.d.ts +24 -1
  128. package/dist/components/import-assets.js +3 -1
  129. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  130. package/dist/components/keyboard-shortcuts.js +28 -9
  131. package/dist/error-overlay/remotion-overlay/CodeFrame.js +29 -18
  132. package/dist/esm/LazyModels-gfmpcy4h.mjs +11 -0
  133. package/dist/esm/LazyModels-m1rf06wh.mjs +11 -0
  134. package/dist/esm/{HighlightedElementSource-jfc66k4p.mjs → SyntaxHighlightedSource-3xks91rz.mjs} +4 -4
  135. package/dist/esm/{TranscriptionModal-916jqhry.mjs → TranscriptionModal-8pvrehg4.mjs} +7 -7
  136. package/dist/esm/{VideoMattingModal-2tm79s9b.mjs → VideoMattingModal-fefbzgka.mjs} +7 -7
  137. package/dist/esm/{index-xhe2m2qr.mjs → index-0x13f28h.mjs} +35 -13
  138. package/dist/esm/{index-sgtmgc4h.mjs → index-1089795y.mjs} +3 -3
  139. package/dist/esm/{index-hy4xcgty.mjs → index-41kqns5c.mjs} +5 -3
  140. package/dist/esm/{index-6cvm9a65.mjs → index-ggqpre9v.mjs} +2868 -2099
  141. package/dist/esm/{index-czwvnn9g.mjs → index-hbezgbbq.mjs} +1 -1
  142. package/dist/esm/{index-1x7bsdh6.mjs → index-jrw61pkj.mjs} +2 -2
  143. package/dist/esm/{index-jg13hf2g.mjs → index-k426ye99.mjs} +2 -1
  144. package/dist/esm/{index-te66vvrp.mjs → index-mww32xc8.mjs} +4 -4
  145. package/dist/esm/{index-x7t2y7ws.mjs → index-s848rffx.mjs} +6985 -5956
  146. package/dist/esm/{index-3hgr6gjx.mjs → index-tzxb8808.mjs} +1 -1
  147. package/dist/esm/{index-5qddp5h7.mjs → index-vsxrxfpj.mjs} +1 -1
  148. package/dist/esm/index.mjs +3 -3
  149. package/dist/esm/internals.mjs +8 -8
  150. package/dist/esm/previewEntry.mjs +8 -8
  151. package/dist/esm/renderEntry.mjs +3 -3
  152. package/dist/helpers/colors.d.ts +1 -0
  153. package/dist/helpers/colors.js +4 -3
  154. package/dist/helpers/get-git-menu-item.d.ts +4 -0
  155. package/dist/helpers/get-git-menu-item.js +8 -1
  156. package/dist/helpers/get-sequence-double-click-action.d.ts +3 -3
  157. package/dist/helpers/get-sequence-double-click-action.js +2 -2
  158. package/dist/helpers/inject-css.js +2 -2
  159. package/dist/helpers/pointer-session.d.ts +1 -0
  160. package/dist/helpers/pointer-session.js +10 -1
  161. package/dist/helpers/prism-vsc-dark-plus.d.ts +1 -0
  162. package/dist/helpers/prism-vsc-dark-plus.js +305 -0
  163. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  164. package/dist/helpers/use-create-composition.d.ts +1 -0
  165. package/dist/helpers/use-create-composition.js +17 -7
  166. package/dist/helpers/use-keybinding.d.ts +1 -1
  167. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  168. package/dist/helpers/use-media-metadata.js +5 -1
  169. package/dist/helpers/use-menu-structure.js +6 -2
  170. package/dist/helpers/use-rename-composition.d.ts +1 -0
  171. package/dist/helpers/use-rename-composition.js +16 -5
  172. package/dist/icons/skills.js +1 -1
  173. package/dist/renderEntry.js +2 -2
  174. package/dist/state/modals.d.ts +13 -1
  175. package/dist/state/z-index.js +1 -3
  176. package/package.json +20 -20
  177. package/dist/components/HighlightedElementSource.d.ts +0 -5
  178. package/dist/esm/LazyModels-2trdm224.mjs +0 -11
  179. package/dist/esm/LazyModels-fjb5ckaq.mjs +0 -11
  180. package/dist/helpers/prism-tomorrow.d.ts +0 -1
  181. package/dist/helpers/prism-tomorrow.js +0 -151
  182. /package/dist/esm/{resolve-composition-component-location-14148845.mjs → resolve-composition-component-location-bt2d6qxq.mjs} +0 -0
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export declare const ActionTooltip: React.FC<{
3
+ readonly label: string;
4
+ readonly shortcut: string | null;
5
+ /** Hover delay in milliseconds. Pass null to show immediately. */
6
+ readonly delay: number | null;
7
+ readonly dismissOnClick: boolean;
8
+ readonly side?: 'top' | 'right';
9
+ readonly triggerStyle?: React.CSSProperties;
10
+ readonly children: React.ReactNode;
11
+ }>;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionTooltip = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const react_dom_1 = require("react-dom");
7
+ const colors_1 = require("../helpers/colors");
8
+ const z_index_1 = require("../state/z-index");
9
+ const portals_1 = require("./Menu/portals");
10
+ const styles_1 = require("./Menu/styles");
11
+ const defaultTriggerStyle = { display: 'inline-flex' };
12
+ const tooltipStyle = {
13
+ position: 'fixed',
14
+ display: 'flex',
15
+ alignItems: 'center',
16
+ gap: 6,
17
+ backgroundColor: colors_1.TIMELINE_BACKGROUND_COLOR,
18
+ color: colors_1.WHITE_ALPHA_90,
19
+ borderRadius: 6,
20
+ padding: '6px 8px',
21
+ fontSize: 12,
22
+ lineHeight: '16px',
23
+ whiteSpace: 'pre-wrap',
24
+ overflowWrap: 'anywhere',
25
+ maxWidth: 'calc(100vw - 16px)',
26
+ boxShadow: styles_1.SHADOW_TOWARDS_TOP,
27
+ pointerEvents: 'none',
28
+ };
29
+ const labelStyle = {
30
+ font: 'inherit',
31
+ color: 'inherit',
32
+ minWidth: 0,
33
+ };
34
+ const shortcutStyle = {
35
+ ...labelStyle,
36
+ backgroundColor: colors_1.WHITE_ALPHA_10,
37
+ borderRadius: 3,
38
+ padding: '0 4px',
39
+ minWidth: 16,
40
+ textAlign: 'center',
41
+ whiteSpace: 'nowrap',
42
+ flexShrink: 0,
43
+ };
44
+ let visibleTooltipCount = 0;
45
+ let lastTooltipHiddenAt = null;
46
+ const TOOLTIP_SKIP_DELAY_WINDOW = 300;
47
+ const ActionTooltip = ({ label, shortcut, delay, dismissOnClick, side = 'top', triggerStyle, children, }) => {
48
+ var _a, _b;
49
+ const triggerRef = (0, react_1.useRef)(null);
50
+ const tooltipRef = (0, react_1.useRef)(null);
51
+ const timer = (0, react_1.useRef)(null);
52
+ const [visible, setVisible] = (0, react_1.useState)(false);
53
+ const [position, setPosition] = (0, react_1.useState)(null);
54
+ const { currentZIndex } = (0, z_index_1.useZIndex)();
55
+ (0, react_1.useLayoutEffect)(() => {
56
+ if (!visible) {
57
+ return;
58
+ }
59
+ visibleTooltipCount++;
60
+ return () => {
61
+ visibleTooltipCount--;
62
+ lastTooltipHiddenAt = Date.now();
63
+ };
64
+ }, [visible]);
65
+ const hide = (0, react_1.useCallback)(() => {
66
+ if (timer.current !== null) {
67
+ clearTimeout(timer.current);
68
+ timer.current = null;
69
+ }
70
+ setVisible(false);
71
+ setPosition(null);
72
+ }, []);
73
+ const show = (0, react_1.useCallback)(() => {
74
+ if (timer.current !== null) {
75
+ clearTimeout(timer.current);
76
+ timer.current = null;
77
+ }
78
+ setVisible(true);
79
+ }, []);
80
+ const onPointerEnter = (0, react_1.useCallback)((event) => {
81
+ if (event.pointerType === 'touch' ||
82
+ timer.current !== null ||
83
+ !event.currentTarget.contains(event.target)) {
84
+ return;
85
+ }
86
+ // Keep adjacent controls instant, including crossing the gap between them.
87
+ if (!delay ||
88
+ visibleTooltipCount > 0 ||
89
+ (lastTooltipHiddenAt !== null &&
90
+ Date.now() - lastTooltipHiddenAt < TOOLTIP_SKIP_DELAY_WINDOW)) {
91
+ show();
92
+ return;
93
+ }
94
+ timer.current = setTimeout(show, delay);
95
+ }, [delay, show]);
96
+ (0, react_1.useEffect)(() => {
97
+ const onKeyDown = (event) => {
98
+ if (event.key === 'Escape') {
99
+ hide();
100
+ }
101
+ };
102
+ window.addEventListener('keydown', onKeyDown);
103
+ window.addEventListener('blur', hide);
104
+ window.addEventListener('resize', hide);
105
+ window.addEventListener('scroll', hide, true);
106
+ return () => {
107
+ if (timer.current !== null) {
108
+ clearTimeout(timer.current);
109
+ }
110
+ window.removeEventListener('keydown', onKeyDown);
111
+ window.removeEventListener('blur', hide);
112
+ window.removeEventListener('resize', hide);
113
+ window.removeEventListener('scroll', hide, true);
114
+ };
115
+ }, [hide]);
116
+ (0, react_1.useLayoutEffect)(() => {
117
+ if (!visible || !triggerRef.current || !tooltipRef.current) {
118
+ return;
119
+ }
120
+ const trigger = triggerRef.current.getBoundingClientRect();
121
+ const tooltip = tooltipRef.current.getBoundingClientRect();
122
+ if (side === 'right') {
123
+ const right = trigger.right + 4;
124
+ setPosition({
125
+ left: right + tooltip.width <= window.innerWidth - 8
126
+ ? right
127
+ : Math.max(8, trigger.left - tooltip.width - 4),
128
+ top: Math.max(8, Math.min(trigger.top + (trigger.height - tooltip.height) / 2, window.innerHeight - tooltip.height - 8)),
129
+ });
130
+ return;
131
+ }
132
+ const above = trigger.top - tooltip.height - 4;
133
+ setPosition({
134
+ left: Math.max(8, Math.min(trigger.left + (trigger.width - tooltip.width) / 2, window.innerWidth - tooltip.width - 8)),
135
+ top: Math.max(8, Math.min(above >= 8 ? above : trigger.bottom + 4, window.innerHeight - tooltip.height - 8)),
136
+ });
137
+ }, [label, shortcut, side, visible]);
138
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
139
+ jsx_runtime_1.jsx("span", { ref: triggerRef, style: { ...defaultTriggerStyle, ...triggerStyle }, onPointerEnter: onPointerEnter, onPointerLeave: hide, onPointerDownCapture: dismissOnClick ? hide : undefined, onClickCapture: dismissOnClick ? hide : undefined, onFocus: (event) => {
140
+ if (event.currentTarget.contains(event.target)) {
141
+ show();
142
+ }
143
+ }, onBlur: hide, children: children }), visible
144
+ ? (0, react_dom_1.createPortal)(jsx_runtime_1.jsxs("div", { ref: tooltipRef, role: "tooltip", className: "css-reset", style: {
145
+ ...tooltipStyle,
146
+ left: (_a = position === null || position === void 0 ? void 0 : position.left) !== null && _a !== void 0 ? _a : 0,
147
+ top: (_b = position === null || position === void 0 ? void 0 : position.top) !== null && _b !== void 0 ? _b : 0,
148
+ visibility: position ? 'visible' : 'hidden',
149
+ }, children: [
150
+ jsx_runtime_1.jsx("span", { style: labelStyle, children: label }), shortcut ? jsx_runtime_1.jsx("kbd", { style: shortcutStyle, children: shortcut }) : null] }), (0, portals_1.getPortal)(currentZIndex))
151
+ : null] }));
152
+ };
153
+ exports.ActionTooltip = ActionTooltip;
@@ -51,6 +51,7 @@ const AppLaunchButton = ({ actionButtonId, ariaLabel, children, disabled, menuAr
51
51
  ? defaultMainSegmentStyle
52
52
  : compactMainSegmentStyle,
53
53
  title,
54
+ tooltipLabel: null,
54
55
  type: 'action',
55
56
  },
56
57
  ...(items.length > 0
@@ -67,6 +68,7 @@ const AppLaunchButton = ({ actionButtonId, ariaLabel, children, disabled, menuAr
67
68
  selectedId: null,
68
69
  style: dropdownSegmentStyle,
69
70
  title: menuAriaLabel,
71
+ tooltipLabel: null,
70
72
  type: 'menu',
71
73
  values: items,
72
74
  },
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { type AssetSelectionModalState } from '../state/modals';
3
+ export declare const AssetSelectorModal: React.FC<{
4
+ readonly state: AssetSelectionModalState;
5
+ readonly readOnlyStudio: boolean;
6
+ }>;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetSelectorModal = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const colors_1 = require("../helpers/colors");
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 RemInput_1 = require("./NewComposition/RemInput");
15
+ const QuickSwitcherContent_1 = require("./QuickSwitcher/QuickSwitcherContent");
16
+ const SegmentedControl_1 = require("./SegmentedControl");
17
+ const panel = {
18
+ maxWidth: 'calc(100vw - 40px)',
19
+ overflow: 'hidden',
20
+ width: 400,
21
+ };
22
+ const sourceSelector = {
23
+ display: 'flex',
24
+ padding: '12px 16px 0',
25
+ };
26
+ const urlContent = {
27
+ boxSizing: 'border-box',
28
+ minHeight: 300,
29
+ padding: 16,
30
+ };
31
+ const compactUrlContent = {
32
+ boxSizing: 'border-box',
33
+ padding: 16,
34
+ };
35
+ const label = {
36
+ color: colors_1.LIGHT_TEXT,
37
+ display: 'block',
38
+ fontFamily: 'sans-serif',
39
+ fontSize: 12,
40
+ marginBottom: 8,
41
+ };
42
+ const previewRow = {
43
+ alignItems: 'center',
44
+ display: 'flex',
45
+ gap: 16,
46
+ minHeight: 112,
47
+ paddingTop: 16,
48
+ };
49
+ const previewImage = {
50
+ display: 'block',
51
+ height: 96,
52
+ objectFit: 'contain',
53
+ width: 96,
54
+ };
55
+ const previewStatus = {
56
+ color: colors_1.LIGHT_TEXT,
57
+ fontFamily: 'sans-serif',
58
+ fontSize: 12,
59
+ lineHeight: 1.5,
60
+ };
61
+ const footer = {
62
+ display: 'flex',
63
+ minWidth: 0,
64
+ width: '100%',
65
+ };
66
+ const isHttpUrl = (value) => {
67
+ try {
68
+ const { protocol } = new URL(value.startsWith('//') ? `https:${value}` : value);
69
+ return protocol === 'http:' || protocol === 'https:';
70
+ }
71
+ catch (_a) {
72
+ return false;
73
+ }
74
+ };
75
+ const AssetSelectorModal = ({ state, readOnlyStudio }) => {
76
+ var _a;
77
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
78
+ const [mode, setMode] = (0, react_1.useState)(() => state.initialUrl === null ? 'project' : 'url');
79
+ const [draft, setDraft] = (0, react_1.useState)((_a = state.initialUrl) !== null && _a !== void 0 ? _a : '');
80
+ const [previewState, setPreviewState] = (0, react_1.useState)(() => state.assetType === 'image' && state.initialUrl !== null
81
+ ? { type: 'loading' }
82
+ : { type: 'empty' });
83
+ const close = (0, react_1.useCallback)(() => {
84
+ setSelectedModal(null);
85
+ }, [setSelectedModal]);
86
+ (0, react_1.useEffect)(() => {
87
+ if (state.assetType !== 'image') {
88
+ setPreviewState({ type: 'empty' });
89
+ return;
90
+ }
91
+ const value = draft.trim();
92
+ if (value === '') {
93
+ setPreviewState({ type: 'empty' });
94
+ return;
95
+ }
96
+ if (!isHttpUrl(value)) {
97
+ setPreviewState({ type: 'invalid' });
98
+ return;
99
+ }
100
+ let cancelled = false;
101
+ const image = new Image();
102
+ setPreviewState({ type: 'loading' });
103
+ image.onload = () => {
104
+ if (!cancelled) {
105
+ setPreviewState({
106
+ type: 'loaded',
107
+ width: image.naturalWidth,
108
+ height: image.naturalHeight,
109
+ });
110
+ }
111
+ };
112
+ image.onerror = () => {
113
+ if (!cancelled) {
114
+ setPreviewState({ type: 'error' });
115
+ }
116
+ };
117
+ image.src = value.startsWith('//') ? `https:${value}` : value;
118
+ return () => {
119
+ cancelled = true;
120
+ image.onload = null;
121
+ image.onerror = null;
122
+ };
123
+ }, [draft, state.assetType]);
124
+ const items = (0, react_1.useMemo)(() => [
125
+ {
126
+ key: 'project',
127
+ label: 'Project assets',
128
+ onClick: () => setMode('project'),
129
+ selected: mode === 'project',
130
+ },
131
+ {
132
+ key: 'url',
133
+ label: 'URL',
134
+ onClick: () => setMode('url'),
135
+ selected: mode === 'url',
136
+ },
137
+ ], [mode]);
138
+ const trimmedDraft = draft.trim();
139
+ const canApply = isHttpUrl(trimmedDraft);
140
+ const invalidDraft = trimmedDraft !== '' && !canApply;
141
+ const apply = (0, react_1.useCallback)(() => {
142
+ if (!canApply) {
143
+ return;
144
+ }
145
+ state.onSelectedUrl(trimmedDraft);
146
+ close();
147
+ }, [canApply, close, state, trimmedDraft]);
148
+ const onSubmit = (0, react_1.useCallback)((event) => {
149
+ event.preventDefault();
150
+ apply();
151
+ }, [apply]);
152
+ const assetTypeLabel = state.assetType.charAt(0).toUpperCase() + state.assetType.slice(1);
153
+ return (jsx_runtime_1.jsxs(ModalContainer_1.ModalContainer, { onEscape: close, onOutsideClick: close, panelStyle: panel, children: [
154
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Replace ${state.assetType}`, onClose: close }), jsx_runtime_1.jsx("div", { style: sourceSelector, children: jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: items, needsWrapping: false, size: "compact" }) }), mode === 'project' ? (jsx_runtime_1.jsx(QuickSwitcherContent_1.QuickSwitcherContent, { assetSelection: state.assetSelection, compositionSelection: null, initialMode: "assets", invocationTimestamp: state.invocationTimestamp, readOnlyStudio: readOnlyStudio })) : (jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [
155
+ jsx_runtime_1.jsxs("div", { style: state.assetType === 'image' ? urlContent : compactUrlContent, children: [
156
+ jsx_runtime_1.jsxs("label", { htmlFor: "remotion-asset-url", style: label, children: [assetTypeLabel, " URL"] }), jsx_runtime_1.jsx(RemInput_1.RemotionInput, { id: "remotion-asset-url", autoFocus: true, onChange: (event) => setDraft(event.target.value), placeholder: `https://example.com/${state.assetType}`, rightAlign: false, status: invalidDraft ? 'error' : 'ok', type: "url", value: draft }), state.assetType === 'image' ? (jsx_runtime_1.jsxs("div", { style: previewRow, role: "status", children: [previewState.type === 'loaded' ? (jsx_runtime_1.jsx("img", { alt: "Image URL preview", src: trimmedDraft.startsWith('//')
157
+ ? `https:${trimmedDraft}`
158
+ : trimmedDraft, style: previewImage })) : null, jsx_runtime_1.jsx("div", { style: previewState.type === 'error'
159
+ ? { ...previewStatus, color: colors_1.FAIL_COLOR }
160
+ : previewStatus, children: previewState.type === 'empty'
161
+ ? 'Enter an image URL.'
162
+ : previewState.type === 'invalid'
163
+ ? 'Enter an HTTP(S) URL.'
164
+ : previewState.type === 'loading'
165
+ ? 'Loading preview…'
166
+ : previewState.type === 'error'
167
+ ? 'Preview unavailable. You can still replace the source.'
168
+ : `${previewState.width} × ${previewState.height}` })
169
+ ] })) : null] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { style: footer, children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", flex: 1, justify: "flex-end", children: [
170
+ jsx_runtime_1.jsx(Button_1.Button, { onClick: close, children: "Cancel" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsxs(ModalButton_1.ModalButton, { disabled: !canApply, onClick: apply, children: ["Replace ", state.assetType] })
171
+ ] }) })
172
+ ] }))] }));
173
+ };
174
+ exports.AssetSelectorModal = AssetSelectorModal;
@@ -155,6 +155,7 @@ const Canvas = ({ canvasContent, size }) => {
155
155
  const [pendingElementInstallRequests, setPendingElementInstallRequests] = (0, react_1.useState)([]);
156
156
  const [activeElementInstallRequest, setActiveElementInstallRequest] = (0, react_1.useState)(null);
157
157
  const lastFocusedAtRef = (0, react_1.useRef)(typeof document === 'undefined' || document.hasFocus() ? Date.now() : null);
158
+ const unsupportedDropNotifiedRef = (0, react_1.useRef)(false);
158
159
  const [assetResolution, setAssetResolution] = (0, react_1.useState)(null);
159
160
  const metadataRequestRef = (0, react_1.useRef)(0);
160
161
  const currentCompositionId = canvasContent.type === 'composition' ? canvasContent.compositionId : null;
@@ -622,7 +623,7 @@ const Canvas = ({ canvasContent, size }) => {
622
623
  }, [previewServerClientId, subscribeToEvent]);
623
624
  (0, react_1.useEffect)(() => {
624
625
  const onMessage = (event) => {
625
- var _a, _b;
626
+ var _a, _b, _c;
626
627
  const elementLibrary = document.querySelector('iframe[data-remotion-element-library]');
627
628
  if (event.source !== (elementLibrary === null || elementLibrary === void 0 ? void 0 : elementLibrary.contentWindow) ||
628
629
  !studio_protocol_1.StudioProtocolInternals.isAllowedStudioProtocolPageOrigin(event.origin)) {
@@ -646,7 +647,8 @@ const Canvas = ({ canvasContent, size }) => {
646
647
  element: {
647
648
  ...payload.element,
648
649
  durationInFrames: (_a = payload.element.durationInFrames) !== null && _a !== void 0 ? _a : null,
649
- installationMode: (_b = payload.element.installationMode) !== null && _b !== void 0 ? _b : null,
650
+ initialProps: (_b = payload.element.initialProps) !== null && _b !== void 0 ? _b : null,
651
+ installationMode: (_c = payload.element.installationMode) !== null && _c !== void 0 ? _c : null,
650
652
  },
651
653
  from: null,
652
654
  id: crypto.randomUUID(),
@@ -842,10 +844,17 @@ const Canvas = ({ canvasContent, size }) => {
842
844
  var _a;
843
845
  var _b;
844
846
  if (!(0, drop_handler_data_1.isSupportedDropEvent)(event) || !isDragEventInsideCanvas(event)) {
847
+ unsupportedDropNotifiedRef.current = false;
845
848
  setCompositionDropPreview(null);
846
849
  return;
847
850
  }
848
851
  const mayBeCanvasCapture = (0, drop_handler_data_1.isFileDragEvent)(event) && !window.remotion_isReadOnlyStudio;
852
+ const shouldNotifyAboutUnsupportedDrop = cannotAddSequence && !mayBeCanvasCapture;
853
+ if (shouldNotifyAboutUnsupportedDrop &&
854
+ !unsupportedDropNotifiedRef.current) {
855
+ (0, NotificationCenter_1.showCannotAddSequenceDropNotification)();
856
+ }
857
+ unsupportedDropNotifiedRef.current = shouldNotifyAboutUnsupportedDrop;
849
858
  if (!canDropAssets && !cannotAddSequence && !mayBeCanvasCapture) {
850
859
  setCompositionDropPreview(null);
851
860
  return;
@@ -938,14 +947,18 @@ const Canvas = ({ canvasContent, size }) => {
938
947
  return;
939
948
  }
940
949
  }
950
+ unsupportedDropNotifiedRef.current = false;
941
951
  setCompositionDropPreview(null);
942
952
  }, []);
943
953
  const onDragEnd = (0, react_1.useCallback)(() => {
954
+ unsupportedDropNotifiedRef.current = false;
944
955
  setCompositionDropPreview(null);
945
956
  }, []);
946
957
  const onDrop = (0, react_1.useCallback)(async (event) => {
947
958
  var _a, _b;
948
959
  var _c, _d;
960
+ const unsupportedDropWasNotified = unsupportedDropNotifiedRef.current;
961
+ unsupportedDropNotifiedRef.current = false;
949
962
  setCompositionDropPreview(null);
950
963
  if (!(0, drop_handler_data_1.isSupportedDropEvent)(event) || !isDragEventInsideCanvas(event)) {
951
964
  return;
@@ -974,7 +987,9 @@ const Canvas = ({ canvasContent, size }) => {
974
987
  if (cannotAddSequence) {
975
988
  event.preventDefault();
976
989
  event.stopPropagation();
977
- (0, NotificationCenter_1.showNotification)('Cannot insert items into this composition component', 3000);
990
+ if (!unsupportedDropWasNotified) {
991
+ (0, NotificationCenter_1.showCannotAddSequenceDropNotification)();
992
+ }
978
993
  return;
979
994
  }
980
995
  if (!canDropAssets ||
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CheckboardToggle = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const no_react_1 = require("remotion/no-react");
7
6
  const colors_1 = require("../helpers/colors");
8
7
  const use_keybinding_1 = require("../helpers/use-keybinding");
9
8
  const use_keyboard_shortcut_label_1 = require("../helpers/use-keyboard-shortcut-label");
10
9
  const checkerboard_1 = require("../state/checkerboard");
10
+ const ActionTooltip_1 = require("./ActionTooltip");
11
11
  const ControlButton_1 = require("./ControlButton");
12
+ const buttonStyle = { width: 26 };
12
13
  const CheckboardToggle = () => {
13
14
  const { checkerboard, setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
14
15
  const onClick = (0, react_1.useCallback)(() => {
@@ -17,14 +18,11 @@ const CheckboardToggle = () => {
17
18
  });
18
19
  }, [setCheckerboard]);
19
20
  const shortcut = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutLabel)('toggleCheckerboard');
20
- const accessibilityLabel = [
21
- 'Show transparency as checkerboard',
22
- (0, use_keybinding_1.areKeyboardShortcutsDisabled)() || shortcut === '' ? null : `(${shortcut})`,
23
- ]
24
- .filter(no_react_1.NoReactInternals.truthy)
25
- .join(' ');
26
- return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, "aria-pressed": checkerboard, onClick: onClick, children: (color) => (jsx_runtime_1.jsxs("svg", { "aria-hidden": "true", focusable: "false", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: { width: 18, height: 18 }, fill: "none", children: [
27
- jsx_runtime_1.jsx("path", { fill: checkerboard ? colors_1.BLUE : color, d: "M256 48h184c13.3 0 24 10.7 24 24v184H256V48zM48 256h208v208H72c-13.3 0-24-10.7-24-24V256z" }), jsx_runtime_1.jsx("rect", { x: "48", y: "48", width: "416", height: "416", rx: "24", stroke: checkerboard ? colors_1.BLUE : color, strokeWidth: "32" }), jsx_runtime_1.jsx("path", { d: "M256 48v416M48 256h416", stroke: checkerboard ? colors_1.BLUE : color, strokeWidth: "32" })
28
- ] })) }));
21
+ const ariaKeyShortcuts = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutAriaKeyShortcuts)('toggleCheckerboard');
22
+ const accessibilityLabel = 'Show transparency as checkerboard';
23
+ const shortcutsDisabled = (0, use_keybinding_1.areKeyboardShortcutsDisabled)();
24
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Checkerboard", shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-pressed": checkerboard, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaKeyShortcuts || undefined, onClick: onClick, style: buttonStyle, children: (color) => (jsx_runtime_1.jsxs("svg", { "aria-hidden": "true", focusable: "false", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: { width: 18, height: 18 }, fill: "none", children: [
25
+ jsx_runtime_1.jsx("path", { fill: checkerboard ? colors_1.BLUE : color, d: "M256 48h184c13.3 0 24 10.7 24 24v184H256V48zM48 256h208v208H72c-13.3 0-24-10.7-24-24V256z" }), jsx_runtime_1.jsx("rect", { x: "48", y: "48", width: "416", height: "416", rx: "24", stroke: checkerboard ? colors_1.BLUE : color, strokeWidth: "32" }), jsx_runtime_1.jsx("path", { d: "M256 48v416M48 256h416", stroke: checkerboard ? colors_1.BLUE : color, strokeWidth: "32" })
26
+ ] })) }) }));
29
27
  };
30
28
  exports.CheckboardToggle = CheckboardToggle;
@@ -67,7 +67,7 @@ const AlphaSlider = ({ hue, saturation, value, alpha, onChange, onChangeComplete
67
67
  updateFromEvent(ev.clientX, false);
68
68
  },
69
69
  onEnd: (reason, ev) => {
70
- const shouldUseEndEvent = reason === 'pointerup' || reason === 'buttons-released';
70
+ const shouldUseEndEvent = (0, pointer_session_1.isPointerSessionRelease)(reason, ev);
71
71
  updateFromEvent(shouldUseEndEvent && ev ? ev.clientX : lastClientX, true);
72
72
  },
73
73
  });
@@ -49,7 +49,7 @@ const HueSlider = ({ hue, onChange, onChangeComplete }) => {
49
49
  updateFromEvent(ev.clientX, false);
50
50
  },
51
51
  onEnd: (reason, ev) => {
52
- const shouldUseEndEvent = reason === 'pointerup' || reason === 'buttons-released';
52
+ const shouldUseEndEvent = (0, pointer_session_1.isPointerSessionRelease)(reason, ev);
53
53
  updateFromEvent(shouldUseEndEvent && ev ? ev.clientX : lastClientX, true);
54
54
  },
55
55
  });
@@ -63,7 +63,7 @@ const SaturationValueArea = ({ hue, saturation, value, onChange, onChangeComplet
63
63
  updateFromEvent(ev.clientX, ev.clientY, false);
64
64
  },
65
65
  onEnd: (reason, ev) => {
66
- const shouldUseEndEvent = reason === 'pointerup' || reason === 'buttons-released';
66
+ const shouldUseEndEvent = (0, pointer_session_1.isPointerSessionRelease)(reason, ev);
67
67
  updateFromEvent(shouldUseEndEvent && ev ? ev.clientX : lastPosition.clientX, shouldUseEndEvent && ev ? ev.clientY : lastPosition.clientY, true);
68
68
  },
69
69
  });
@@ -238,6 +238,7 @@ const CompositionSelector = () => {
238
238
  dryRun: false,
239
239
  signal: controller.signal,
240
240
  symbolicatedStack: (0, composition_selector_drag_data_1.compositionSelectorDragDataToSymbolicatedStack)(dragData),
241
+ undoRedoNavigation: null,
241
242
  });
242
243
  if (result.success) {
243
244
  notification.dismiss();
@@ -408,6 +408,7 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
408
408
  dryRun: false,
409
409
  signal: new AbortController().signal,
410
410
  symbolicatedStack: (0, composition_selector_drag_data_1.compositionSelectorDragDataToSymbolicatedStack)(dragData),
411
+ undoRedoNavigation: null,
411
412
  });
412
413
  if (result.success) {
413
414
  notification.dismiss();
@@ -128,7 +128,7 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
128
128
  pointerDownPositionRef.current = null;
129
129
  const shouldDeleteGuide = shouldDeleteGuideRef.current;
130
130
  finishGuideInteraction();
131
- if (shouldDeleteGuide || reason !== 'pointerup' || !endEvent) {
131
+ if (shouldDeleteGuide || !(0, pointer_session_1.isPointerSessionRelease)(reason, endEvent)) {
132
132
  return;
133
133
  }
134
134
  if ((0, editor_guide_selection_1.isGuidePointerUpAClick)({