@remotion/studio 4.0.515 → 4.0.516

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 (196) hide show
  1. package/dist/api/restart-studio.js +4 -0
  2. package/dist/components/AssetSelector.js +3 -9
  3. package/dist/components/AssetSelectorItem.d.ts +2 -1
  4. package/dist/components/AssetSelectorItem.js +24 -29
  5. package/dist/components/Canvas.js +7 -4
  6. package/dist/components/CaptionInspector.d.ts +2 -0
  7. package/dist/components/CaptionInspector.js +3 -5
  8. package/dist/components/CompositionSelector.js +6 -3
  9. package/dist/components/CompositionSelectorItem.js +9 -10
  10. package/dist/components/ConfigSelect.d.ts +17 -0
  11. package/dist/components/ConfigSelect.js +50 -0
  12. package/dist/components/CurrentAsset.d.ts +10 -2
  13. package/dist/components/CurrentAsset.js +139 -46
  14. package/dist/components/FixComputedValueModal.js +54 -51
  15. package/dist/components/GlobalKeybindings.js +5 -5
  16. package/dist/components/InlineAction.d.ts +1 -1
  17. package/dist/components/InlineAction.js +12 -2
  18. package/dist/components/InlineCaptionInspector.d.ts +2 -0
  19. package/dist/components/InlineCaptionInspector.js +2 -2
  20. package/dist/components/InlineCompositionName.js +1 -1
  21. package/dist/components/InlineEditableTitle.js +3 -2
  22. package/dist/components/InspectorInfoHeader.js +1 -1
  23. package/dist/components/InspectorOpenInEditor.js +48 -72
  24. package/dist/components/InspectorPanel/AlignmentControls.js +2 -3
  25. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.d.ts +7 -0
  26. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +39 -0
  27. package/dist/components/InspectorPanel/CompositionInspector.js +14 -7
  28. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +10 -4
  29. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +2 -1
  30. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +1 -4
  31. package/dist/components/InspectorPanel/common.d.ts +0 -12
  32. package/dist/components/InspectorPanel/common.js +3 -52
  33. package/dist/components/InspectorPanel/use-composition-actions.js +0 -1
  34. package/dist/components/InspectorPanelLayout.d.ts +1 -1
  35. package/dist/components/InspectorPanelLayout.js +1 -1
  36. package/dist/components/InspectorSequenceSection.js +40 -54
  37. package/dist/components/InstallPackage.d.ts +2 -1
  38. package/dist/components/InstallPackage.js +60 -30
  39. package/dist/components/InstallablePackage.js +37 -11
  40. package/dist/components/KeyboardShortcutsSettings.d.ts +2 -0
  41. package/dist/components/KeyboardShortcutsSettings.js +177 -0
  42. package/dist/components/MenuBuildIndicator.js +1 -1
  43. package/dist/components/Modals.js +6 -5
  44. package/dist/components/NewComposition/CodemodFooter.d.ts +0 -1
  45. package/dist/components/NewComposition/CodemodFooter.js +2 -8
  46. package/dist/components/NewComposition/DeleteComposition.js +1 -1
  47. package/dist/components/NewComposition/DeleteFolder.js +1 -1
  48. package/dist/components/NewComposition/DuplicateComposition.js +1 -1
  49. package/dist/components/NewComposition/InputDragger.js +27 -4
  50. package/dist/components/NewComposition/NewComposition.js +1 -1
  51. package/dist/components/NewComposition/NewFolder.js +1 -3
  52. package/dist/components/NewComposition/RenameComposition.js +1 -1
  53. package/dist/components/NewComposition/RenameFolder.js +1 -1
  54. package/dist/components/NewComposition/use-rename-static-file.js +1 -1
  55. package/dist/components/Notifications/NotificationCenter.d.ts +1 -0
  56. package/dist/components/Notifications/NotificationCenter.js +5 -0
  57. package/dist/components/OptionsPanel.js +9 -12
  58. package/dist/components/PreviewToolbar.js +5 -2
  59. package/dist/components/PreviewToolbarOverflowButton.js +30 -0
  60. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +2 -2
  61. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +14 -30
  62. package/dist/components/RenderButton.js +66 -183
  63. package/dist/components/RenderModal/DataEditor.js +15 -12
  64. package/dist/components/RenderModal/RenderStatusModal.js +0 -1
  65. package/dist/components/RenderModal/SchemaEditor/ZodSwitch.js +3 -1
  66. package/dist/components/RenderModal/SchemaEditor/infer-zod-schema-from-value.d.ts +15 -0
  67. package/dist/components/RenderModal/SchemaEditor/infer-zod-schema-from-value.js +95 -0
  68. package/dist/components/RenderQueue/RenderQueueRemoveItem.js +1 -6
  69. package/dist/components/RenderingSettings.js +7 -4
  70. package/dist/components/RulersAndGuidesToggle.d.ts +2 -0
  71. package/dist/components/RulersAndGuidesToggle.js +23 -0
  72. package/dist/components/SegmentedButton.d.ts +29 -0
  73. package/dist/components/SegmentedButton.js +226 -0
  74. package/dist/components/SelectedOutlineEditingHandles.d.ts +16 -0
  75. package/dist/components/SelectedOutlineEditingHandles.js +66 -0
  76. package/dist/components/SelectedOutlineElement.d.ts +2 -4
  77. package/dist/components/SelectedOutlineElement.js +15 -54
  78. package/dist/components/SelectedOutlineOverlay.js +32 -6
  79. package/dist/components/SelectedOutlinePolygon.d.ts +3 -4
  80. package/dist/components/SelectedOutlinePolygon.js +18 -16
  81. package/dist/components/SelectedOutlineRenderer.js +66 -14
  82. package/dist/components/SettingsModal.d.ts +1 -1
  83. package/dist/components/SettingsModal.js +30 -7
  84. package/dist/components/SettingsModalFooter.js +2 -1
  85. package/dist/components/SkillsSettings.d.ts +2 -0
  86. package/dist/components/SkillsSettings.js +129 -0
  87. package/dist/components/StaticFilePreview.js +7 -1
  88. package/dist/components/StudioSettings.js +7 -48
  89. package/dist/components/Tabs/index.js +1 -1
  90. package/dist/components/Timeline/Timeline.js +0 -1
  91. package/dist/components/Timeline/TimelineAssetField.d.ts +1 -1
  92. package/dist/components/Timeline/TimelineAssetField.js +15 -9
  93. package/dist/components/Timeline/TimelineBooleanField.js +1 -4
  94. package/dist/components/Timeline/TimelineClipboardKeybindings.js +7 -10
  95. package/dist/components/Timeline/TimelineEffectItem.d.ts +1 -0
  96. package/dist/components/Timeline/TimelineEffectItem.js +23 -10
  97. package/dist/components/Timeline/TimelineEffectPropItem.js +15 -2
  98. package/dist/components/Timeline/TimelineExpandedRow.js +5 -4
  99. package/dist/components/Timeline/TimelineFieldLabel.js +4 -2
  100. package/dist/components/Timeline/TimelineFieldRowContent.d.ts +1 -2
  101. package/dist/components/Timeline/TimelineFieldRowContent.js +8 -21
  102. package/dist/components/Timeline/TimelineImageInfo.d.ts +0 -1
  103. package/dist/components/Timeline/TimelineImageInfo.js +13 -32
  104. package/dist/components/Timeline/TimelineKeyframeControls.js +10 -4
  105. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -1
  106. package/dist/components/Timeline/TimelineRotationField.js +0 -2
  107. package/dist/components/Timeline/TimelineRowChrome.d.ts +0 -1
  108. package/dist/components/Timeline/TimelineRowChrome.js +3 -4
  109. package/dist/components/Timeline/TimelineRowLayoutContext.d.ts +0 -1
  110. package/dist/components/Timeline/TimelineRowLayoutContext.js +1 -4
  111. package/dist/components/Timeline/TimelineScaleField.js +2 -6
  112. package/dist/components/Timeline/TimelineSchemaField.js +9 -3
  113. package/dist/components/Timeline/TimelineSelection.js +1 -1
  114. package/dist/components/Timeline/TimelineSequence.d.ts +2 -0
  115. package/dist/components/Timeline/TimelineSequence.js +110 -19
  116. package/dist/components/Timeline/TimelineSequenceItem.js +5 -5
  117. package/dist/components/Timeline/TimelineSequencePropItem.js +15 -2
  118. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +4 -2
  119. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +85 -91
  120. package/dist/components/Timeline/TimelineTrack.js +1 -1
  121. package/dist/components/Timeline/TimelineTransformOriginField.js +0 -4
  122. package/dist/components/Timeline/TimelineTranslateField.js +0 -4
  123. package/dist/components/Timeline/TimelineVirtualization.js +3 -1
  124. package/dist/components/Timeline/duplicate-selected-timeline-item.js +3 -12
  125. package/dist/components/Timeline/get-copy-context-for-agents-menu-item.d.ts +4 -0
  126. package/dist/components/Timeline/get-copy-context-for-agents-menu-item.js +26 -0
  127. package/dist/components/Timeline/get-sequence-context-menu-items.js +2 -19
  128. package/dist/components/Timeline/get-timeline-sequence-visible-layout.d.ts +6 -1
  129. package/dist/components/Timeline/get-timeline-sequence-visible-layout.js +11 -4
  130. package/dist/components/Timeline/split-selected-timeline-item.js +0 -1
  131. package/dist/components/Timeline/timeline-field-row-layout.d.ts +1 -1
  132. package/dist/components/Timeline/timeline-field-row-layout.js +4 -7
  133. package/dist/components/Timeline/timeline-field-utils.js +0 -2
  134. package/dist/components/Timeline/use-timeline-asset-drop.js +1 -0
  135. package/dist/components/TimelineCombobox.js +25 -160
  136. package/dist/components/TimelineInOutToggle.js +4 -1
  137. package/dist/components/duplicate-jsx-node-api.d.ts +2 -0
  138. package/dist/components/duplicate-jsx-node-api.js +12 -0
  139. package/dist/components/effect-drag-and-drop.js +1 -4
  140. package/dist/components/handle-drop.d.ts +2 -1
  141. package/dist/components/handle-drop.js +3 -3
  142. package/dist/components/import-assets.js +9 -65
  143. package/dist/components/keyboard-shortcuts.d.ts +10 -0
  144. package/dist/components/keyboard-shortcuts.js +135 -0
  145. package/dist/components/selected-outline-control-layout.js +2 -6
  146. package/dist/components/selected-outline-measurement.d.ts +1 -1
  147. package/dist/components/selected-outline-measurement.js +16 -3
  148. package/dist/components/use-delete-asset.d.ts +1 -0
  149. package/dist/components/use-delete-asset.js +40 -0
  150. package/dist/components/use-selected-outline-control-target.d.ts +11 -0
  151. package/dist/components/use-selected-outline-control-target.js +79 -0
  152. package/dist/esm/{chunk-s6k99gh2.js → chunk-4bxz1d3g.js} +3 -2
  153. package/dist/esm/{chunk-v5a8vpv4.js → chunk-w4244j4n.js} +17766 -17618
  154. package/dist/esm/index.mjs +3 -0
  155. package/dist/esm/internals.mjs +17765 -17617
  156. package/dist/esm/previewEntry.mjs +17570 -17422
  157. package/dist/esm/renderEntry.mjs +2 -2
  158. package/dist/helpers/add-asset-cache-bust.d.ts +4 -0
  159. package/dist/helpers/add-asset-cache-bust.js +10 -0
  160. package/dist/helpers/calculate-timeline.js +2 -1
  161. package/dist/helpers/colors.d.ts +2 -0
  162. package/dist/helpers/colors.js +6 -2
  163. package/dist/helpers/drag-aware-double-click.d.ts +6 -0
  164. package/dist/helpers/drag-aware-double-click.js +20 -0
  165. package/dist/helpers/get-asset-metadata.js +25 -16
  166. package/dist/helpers/get-sequence-double-click-action.d.ts +2 -1
  167. package/dist/helpers/get-sequence-double-click-action.js +7 -1
  168. package/dist/helpers/get-timeline-sequence-layout.d.ts +4 -1
  169. package/dist/helpers/get-timeline-sequence-layout.js +15 -6
  170. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +2 -1
  171. package/dist/helpers/hoverable.d.ts +1 -0
  172. package/dist/helpers/hoverable.js +2 -1
  173. package/dist/helpers/inject-css.js +3 -1
  174. package/dist/helpers/open-in-remotion-convert.d.ts +7 -0
  175. package/dist/helpers/open-in-remotion-convert.js +18 -0
  176. package/dist/helpers/use-media-metadata.d.ts +2 -1
  177. package/dist/helpers/use-media-metadata.js +12 -5
  178. package/dist/helpers/use-menu-structure.js +32 -32
  179. package/dist/icons/align-center-horizontal.js +1 -1
  180. package/dist/icons/align-left.js +1 -1
  181. package/dist/icons/align-right.js +1 -1
  182. package/dist/icons/keyboard.d.ts +4 -0
  183. package/dist/icons/keyboard.js +10 -0
  184. package/dist/icons/license.d.ts +4 -0
  185. package/dist/icons/license.js +8 -0
  186. package/dist/icons/package.d.ts +4 -0
  187. package/dist/icons/package.js +8 -0
  188. package/dist/icons/react.js +1 -1
  189. package/dist/icons/remotion-convert.d.ts +4 -0
  190. package/dist/icons/remotion-convert.js +10 -0
  191. package/dist/icons/skills.d.ts +4 -0
  192. package/dist/icons/skills.js +10 -0
  193. package/dist/state/modals.d.ts +2 -5
  194. package/package.json +12 -12
  195. package/dist/components/KeyboardShortcutsExplainer.d.ts +0 -2
  196. package/dist/components/KeyboardShortcutsExplainer.js +0 -194
@@ -1,181 +1,46 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.TimelineCombobox = void 0;
7
4
  const jsx_runtime_1 = require("react/jsx-runtime");
8
- const player_1 = require("@remotion/player");
9
- const react_1 = require("react");
10
- const react_dom_1 = __importDefault(require("react-dom"));
11
5
  const colors_1 = require("../helpers/colors");
12
- const mobile_layout_1 = require("../helpers/mobile-layout");
13
- const noop_1 = require("../helpers/noop");
14
6
  const caret_1 = require("../icons/caret");
15
- const z_index_1 = require("../state/z-index");
16
7
  const layout_1 = require("./layout");
17
- const is_menu_item_1 = require("./Menu/is-menu-item");
18
- const portals_1 = require("./Menu/portals");
19
- const styles_1 = require("./Menu/styles");
20
- const MenuContent_1 = require("./NewComposition/MenuContent");
21
- const container = {
22
- boxSizing: 'border-box',
23
- border: 'none',
24
- borderRadius: 3,
25
- height: 24,
26
- padding: '0 4px',
27
- fontFamily: 'inherit',
28
- maxWidth: '100%',
8
+ const SegmentedButton_1 = require("./SegmentedButton");
9
+ const segmentedButtonStyle = {
10
+ height: 28,
29
11
  };
30
12
  const label = {
31
13
  flex: 'none',
32
- overflow: 'hidden',
33
- textOverflow: 'ellipsis',
34
14
  fontFamily: 'inherit',
35
15
  fontSize: 12,
36
16
  lineHeight: '16px',
37
- color: colors_1.WHITE_ALPHA_80,
38
17
  minWidth: 0,
18
+ overflow: 'hidden',
39
19
  textAlign: 'left',
20
+ textOverflow: 'ellipsis',
40
21
  whiteSpace: 'nowrap',
41
22
  };
42
23
  const TimelineCombobox = ({ values, selectedId, title, labelWidth = 32, renderLeftItem, unhoveredIconColor = colors_1.LIGHT_TEXT, }) => {
43
- const [hovered, setIsHovered] = (0, react_1.useState)(false);
44
- const [opened, setOpened] = (0, react_1.useState)(false);
45
- const ref = (0, react_1.useRef)(null);
46
- const { tabIndex, currentZIndex } = (0, z_index_1.useZIndex)();
47
- const size = player_1.PlayerInternals.useElementSize(ref, {
48
- triggerOnWindowResize: true,
49
- shouldApplyCssTransforms: true,
50
- });
51
- const refresh = size === null || size === void 0 ? void 0 : size.refresh;
52
- const onHide = (0, react_1.useCallback)(() => {
53
- setOpened(false);
54
- }, []);
55
- const onOverlayPointerDown = (0, react_1.useCallback)((e) => {
56
- e.stopPropagation();
57
- }, []);
58
- (0, react_1.useEffect)(() => {
59
- const { current } = ref;
60
- if (!current) {
61
- return;
62
- }
63
- const onMouseEnter = () => setIsHovered(true);
64
- const onMouseLeave = () => setIsHovered(false);
65
- const onPointerDown = (e) => {
66
- e.stopPropagation();
67
- return setOpened((isOpened) => {
68
- if (!isOpened) {
69
- refresh === null || refresh === void 0 ? void 0 : refresh();
70
- }
71
- return !isOpened;
72
- });
73
- };
74
- const onClick = (e) => {
75
- e.stopPropagation();
76
- const isKeyboardInitiated = e.detail === 0;
77
- if (!isKeyboardInitiated) {
78
- return;
79
- }
80
- return setOpened((isOpened) => {
81
- if (!isOpened) {
82
- refresh === null || refresh === void 0 ? void 0 : refresh();
83
- window.addEventListener('pointerup', (evt) => {
84
- if (!(0, is_menu_item_1.isMenuItem)(evt.target)) {
85
- setOpened(false);
86
- }
87
- }, { once: true });
88
- }
89
- return !isOpened;
90
- });
91
- };
92
- current.addEventListener('mouseenter', onMouseEnter);
93
- current.addEventListener('mouseleave', onMouseLeave);
94
- current.addEventListener('pointerdown', onPointerDown);
95
- current.addEventListener('click', onClick);
96
- return () => {
97
- current.removeEventListener('mouseenter', onMouseEnter);
98
- current.removeEventListener('mouseleave', onMouseLeave);
99
- current.removeEventListener('pointerdown', onPointerDown);
100
- current.removeEventListener('click', onClick);
101
- };
102
- }, [refresh]);
103
- const spaceToBottom = (0, react_1.useMemo)(() => {
104
- const margin = 10;
105
- if (size && opened) {
106
- return size.windowSize.height - (size.top + size.height) - margin;
107
- }
108
- return 0;
109
- }, [opened, size]);
110
- const spaceToTop = (0, react_1.useMemo)(() => {
111
- const margin = 10;
112
- if (size && opened) {
113
- return size.top - margin;
114
- }
115
- return 0;
116
- }, [opened, size]);
117
- const derivedMaxHeight = (0, react_1.useMemo)(() => {
118
- return spaceToTop > spaceToBottom ? spaceToTop : spaceToBottom;
119
- }, [spaceToBottom, spaceToTop]);
120
- const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
121
- const portalStyle = (0, react_1.useMemo)(() => {
122
- if (!opened || !size) {
123
- return null;
124
- }
125
- const spaceToRight = size.windowSize.width - size.left;
126
- const spaceToLeft = size.left + size.width;
127
- const minSpaceRequired = isMobileLayout
128
- ? styles_1.MAX_MOBILE_MENU_WIDTH
129
- : styles_1.MAX_MENU_WIDTH;
130
- const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
131
- const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
132
- const canOpenOnRight = spaceToRight >= minSpaceRequired;
133
- const horizontalLayout = canOpenOnRight ? 'left' : 'right';
134
- return {
135
- ...(verticalLayout === 'top'
136
- ? {
137
- ...styles_1.menuContainerTowardsBottom,
138
- top: size.top + size.height,
139
- }
140
- : {
141
- ...styles_1.menuContainerTowardsTop,
142
- bottom: size.windowSize.height - size.top,
143
- }),
144
- ...(horizontalLayout === 'left'
145
- ? { left: size.left }
146
- : canOpenOnLeft
147
- ? { right: size.windowSize.width - size.left - size.width }
148
- : { left: 0 }),
149
- };
150
- }, [isMobileLayout, opened, size, spaceToBottom, spaceToTop]);
151
24
  const selected = values.find((value) => value.id === selectedId);
152
- const style = (0, react_1.useMemo)(() => {
153
- return {
154
- ...container,
155
- userSelect: 'none',
156
- WebkitUserSelect: 'none',
157
- display: 'inline-flex',
158
- flexDirection: 'row',
159
- alignItems: 'center',
160
- backgroundColor: (0, colors_1.getBackgroundFromHoverState)({
161
- hovered,
162
- selected: opened,
163
- }),
164
- };
165
- }, [hovered, opened]);
166
- const foregroundColor = hovered || opened ? colors_1.WHITE : colors_1.WHITE_ALPHA_80;
167
- const labelStyle = (0, react_1.useMemo)(() => {
168
- return {
169
- ...label,
170
- width: labelWidth,
171
- color: foregroundColor,
172
- };
173
- }, [foregroundColor, labelWidth]);
174
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
175
- jsx_runtime_1.jsxs("button", { ref: ref, title: title, "aria-label": title, tabIndex: tabIndex, type: "button", style: style, className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, children: [renderLeftItem ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [renderLeftItem(foregroundColor), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
176
- ] })) : null, selected ? (jsx_runtime_1.jsx("div", { title: typeof selected.label === 'string' ? selected.label : undefined, style: labelStyle, children: selected.label })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(caret_1.CaretDown, { color: hovered || opened ? colors_1.WHITE : unhoveredIconColor })
177
- ] }), portalStyle
178
- ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, onPointerDown: onOverlayPointerDown, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHide, onEscape: onHide, children: jsx_runtime_1.jsx("div", { style: portalStyle, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: noop_1.noop, onPreviousMenu: noop_1.noop, values: values, onHide: onHide, leaveLeftSpace: true, preselectIndex: values.findIndex((value) => selected && value.id === selected.id), topItemCanBeUnselected: false, fixedHeight: derivedMaxHeight }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
179
- : null] }));
25
+ const segments = [
26
+ {
27
+ ariaLabel: title,
28
+ buttonId: null,
29
+ disabled: false,
30
+ idleColor: unhoveredIconColor,
31
+ leaveLeftSpace: true,
32
+ onOpenChange: null,
33
+ renderContent: (color) => (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [renderLeftItem ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [renderLeftItem(color), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
34
+ ] })) : null, selected ? (jsx_runtime_1.jsx("div", { title: typeof selected.label === 'string' ? selected.label : undefined, style: { ...label, width: labelWidth }, children: selected.label })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(caret_1.CaretDown, { color: color })
35
+ ] })),
36
+ segmentId: 'selector',
37
+ selectedId,
38
+ style: { fontFamily: 'inherit', padding: '0 4px' },
39
+ title,
40
+ type: 'menu',
41
+ values,
42
+ },
43
+ ];
44
+ return (jsx_runtime_1.jsx(SegmentedButton_1.SegmentedButton, { segments: segments, style: segmentedButtonStyle, title: null }));
180
45
  };
181
46
  exports.TimelineCombobox = TimelineCombobox;
@@ -22,6 +22,9 @@ const style = {
22
22
  width: 17,
23
23
  height: 17,
24
24
  };
25
+ const buttonStyle = {
26
+ width: 18,
27
+ };
25
28
  exports.inOutHandles = (0, react_1.createRef)();
26
29
  exports.defaultInOutValue = { inFrame: null, outFrame: null };
27
30
  const TimelineInOutPointToggle = () => {
@@ -243,7 +246,7 @@ const TimelineInOutPointToggle = () => {
243
246
  };
244
247
  }, [confId, onInMark, onInOutClear, onOutMark]);
245
248
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
246
- jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: getTooltipText('In', 'I'), "aria-label": getTooltipText('In', 'I'), onClick: onInMark, onContextMenu: clearInMark, disabled: !videoConfig || isFirstFrame, children: (color) => (jsx_runtime_1.jsx(timelineInOutPointer_1.TimelineInPointer, { color: inFrame === null ? color : colors_1.BLUE, style: style })) }), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: getTooltipText('Out', 'O'), "aria-label": getTooltipText('Out', 'O'), onClick: onOutMark, onContextMenu: clearOutMark, disabled: !videoConfig || isLastFrame, children: (color) => (jsx_runtime_1.jsx(timelineInOutPointer_1.TimelineOutPointer, { color: outFrame === null ? color : colors_1.BLUE, style: style })) })
249
+ jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: getTooltipText('In', 'I'), "aria-label": getTooltipText('In', 'I'), style: buttonStyle, onClick: onInMark, onContextMenu: clearInMark, disabled: !videoConfig || isFirstFrame, children: (color) => (jsx_runtime_1.jsx(timelineInOutPointer_1.TimelineInPointer, { color: inFrame === null ? color : colors_1.BLUE, style: style })) }), jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: getTooltipText('Out', 'O'), "aria-label": getTooltipText('Out', 'O'), style: buttonStyle, onClick: onOutMark, onContextMenu: clearOutMark, disabled: !videoConfig || isLastFrame, children: (color) => (jsx_runtime_1.jsx(timelineInOutPointer_1.TimelineOutPointer, { color: outFrame === null ? color : colors_1.BLUE, style: style })) })
247
250
  ] }));
248
251
  };
249
252
  exports.TimelineInOutPointToggle = TimelineInOutPointToggle;
@@ -0,0 +1,2 @@
1
+ import type { DuplicateJsxNodeRequest, DuplicateJsxNodeResponse } from '@remotion/studio-shared';
2
+ export declare const duplicateJsxNode: (request: DuplicateJsxNodeRequest) => Promise<DuplicateJsxNodeResponse>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.duplicateJsxNode = void 0;
4
+ const browser_studio_operations_1 = require("../helpers/browser-studio-operations");
5
+ const call_api_1 = require("./call-api");
6
+ const duplicateJsxNode = (request) => {
7
+ const browserStudioOperations = (0, browser_studio_operations_1.getBrowserStudioOperations)();
8
+ return browserStudioOperations
9
+ ? browserStudioOperations.duplicateJsxNode(request)
10
+ : (0, call_api_1.callApi)('/api/duplicate-jsx-node', request);
11
+ };
12
+ exports.duplicateJsxNode = duplicateJsxNode;
@@ -45,10 +45,7 @@ const addEffectToSequence = async ({ clientId, effect, fileName, nodePath, }) =>
45
45
  effectConfig: effect.config,
46
46
  clientId,
47
47
  });
48
- if (result.success) {
49
- (0, NotificationCenter_1.showNotification)(`Added ${effect.name}()`, 2000);
50
- }
51
- else {
48
+ if (!result.success) {
52
49
  (0, NotificationCenter_1.showNotification)(result.reason, 4000);
53
50
  }
54
51
  }
@@ -1,7 +1,7 @@
1
1
  import type { Dimensions } from '../helpers/is-current-selected-still';
2
2
  import { type InsertElementDropPosition } from './import-assets';
3
3
  import type { SvgImportMode } from './SvgImportDialog';
4
- export declare const handleDrop: ({ chooseSvgImportMode, compositionFile, compositionId, destinationDimensions, dropPosition, event, fps, from, preferCompositionStart, }: {
4
+ export declare const handleDrop: ({ chooseSvgImportMode, compositionFile, compositionId, destinationDimensions, dropPosition, event, fps, from, localFiles, preferCompositionStart, }: {
5
5
  chooseSvgImportMode: () => Promise<SvgImportMode | null>;
6
6
  compositionFile: string;
7
7
  compositionId: string;
@@ -10,5 +10,6 @@ export declare const handleDrop: ({ chooseSvgImportMode, compositionFile, compos
10
10
  event: DragEvent;
11
11
  fps: number;
12
12
  from: number | null;
13
+ localFiles: File[] | null;
13
14
  preferCompositionStart: boolean;
14
15
  }) => Promise<void>;
@@ -6,11 +6,11 @@ const drop_handler_data_1 = require("./drop-handler-data");
6
6
  const element_drag_and_drop_1 = require("./element-drag-and-drop");
7
7
  const element_install_request_1 = require("./element-install-request");
8
8
  const import_assets_1 = require("./import-assets");
9
- const handleDrop = async ({ chooseSvgImportMode, compositionFile, compositionId, destinationDimensions, dropPosition, event, fps, from, preferCompositionStart, }) => {
9
+ const handleDrop = async ({ chooseSvgImportMode, compositionFile, compositionId, destinationDimensions, dropPosition, event, fps, from, localFiles, preferCompositionStart, }) => {
10
10
  var _a;
11
11
  var _b;
12
- if ((0, drop_handler_data_1.isFileDragEvent)(event)) {
13
- const files = Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) !== null && _b !== void 0 ? _b : []);
12
+ if (localFiles !== null || (0, drop_handler_data_1.isFileDragEvent)(event)) {
13
+ const files = localFiles !== null && localFiles !== void 0 ? localFiles : Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) !== null && _b !== void 0 ? _b : []);
14
14
  if (files.length === 0) {
15
15
  return;
16
16
  }
@@ -187,30 +187,6 @@ exports.getAssetElementForDroppedFile = getAssetElementForDroppedFile;
187
187
  const isSvgFile = (file) => file.name.toLowerCase().endsWith('.svg');
188
188
  const hasSvgFile = (files) => files.some(isSvgFile);
189
189
  exports.hasSvgFile = hasSvgFile;
190
- const getAssetLabel = (element) => {
191
- if (element.type !== 'asset') {
192
- throw new Error('Expected asset element');
193
- }
194
- if (element.assetType === 'image') {
195
- return '<CanvasImage>';
196
- }
197
- if (element.assetType === 'video') {
198
- return '<Video>';
199
- }
200
- if (element.assetType === 'gif') {
201
- return '<Gif>';
202
- }
203
- if (element.assetType === 'animated-image') {
204
- return '<AnimatedImage>';
205
- }
206
- if (element.assetType === 'audio') {
207
- return '<Audio>';
208
- }
209
- throw new Error('Unsupported asset type');
210
- };
211
- const getComponentLabel = (component) => {
212
- return `<${component.componentName}>`;
213
- };
214
190
  const getCenteredPosition = ({ dimensions, dropPosition, }) => {
215
191
  if (dropPosition === null) {
216
192
  return null;
@@ -478,14 +454,6 @@ const pickFilesToImport = ({ multiple = true, } = {}) => {
478
454
  });
479
455
  };
480
456
  exports.pickFilesToImport = pickFilesToImport;
481
- const notifyInsertedAssets = (insertedLabels) => {
482
- if (insertedLabels.length === 1) {
483
- (0, NotificationCenter_1.showNotification)(`Added ${insertedLabels[0]} to source file`, 2000);
484
- }
485
- else if (insertedLabels.length > 1) {
486
- (0, NotificationCenter_1.showNotification)(`Added ${insertedLabels.length} assets to source file`, 2000);
487
- }
488
- };
489
457
  const notifyUnsupportedFiles = (unsupportedFiles) => {
490
458
  if (unsupportedFiles.length === 1) {
491
459
  (0, NotificationCenter_1.showNotification)(`Cannot add ${unsupportedFiles[0]}: Unsupported file type`, 3000);
@@ -517,6 +485,10 @@ const insertCompositionElement = async ({ compositionFile, compositionId, elemen
517
485
  return true;
518
486
  };
519
487
  const downloadRemoteAsset = (url) => {
488
+ const browserStudioOperations = (0, browser_studio_operations_1.getBrowserStudioOperations)();
489
+ if (browserStudioOperations) {
490
+ return browserStudioOperations.downloadRemoteAsset({ url });
491
+ }
520
492
  return (0, call_api_1.callApi)('/api/download-remote-asset', { url });
521
493
  };
522
494
  const importAssets = async ({ compositionFile, compositionId, destinationDimensions, dropPosition, files, fps, from, preferCompositionStart, svgImportMode, }) => {
@@ -536,7 +508,6 @@ const importAssets = async ({ compositionFile, compositionId, destinationDimensi
536
508
  (0, NotificationCenter_1.showNotification)(`File with name ${differentExistingFile.name} already exists and is different`, 4000);
537
509
  return;
538
510
  }
539
- const insertedLabels = [];
540
511
  const addedStaticFiles = [];
541
512
  const unsupportedFiles = [];
542
513
  const notifyAddedStaticFiles = () => {
@@ -576,7 +547,6 @@ const importAssets = async ({ compositionFile, compositionId, destinationDimensi
576
547
  notifyAddedStaticFiles();
577
548
  return;
578
549
  }
579
- insertedLabels.push('<Interactive.Svg>');
580
550
  continue;
581
551
  }
582
552
  const element = (0, exports.getAssetElementForDroppedFile)({
@@ -626,10 +596,8 @@ const importAssets = async ({ compositionFile, compositionId, destinationDimensi
626
596
  notifyAddedStaticFiles();
627
597
  return;
628
598
  }
629
- insertedLabels.push(getAssetLabel(element));
630
599
  }
631
600
  notifyAddedStaticFiles();
632
- notifyInsertedAssets(insertedLabels);
633
601
  notifyUnsupportedFiles(unsupportedFiles);
634
602
  }
635
603
  catch (error) {
@@ -678,7 +646,7 @@ const insertSvgMarkup = async ({ compositionFile, compositionId, destinationDime
678
646
  catch (_a) {
679
647
  dimensions = null;
680
648
  }
681
- const inserted = await insertCompositionElement({
649
+ await insertCompositionElement({
682
650
  compositionFile,
683
651
  compositionId,
684
652
  from: null,
@@ -692,9 +660,6 @@ const insertSvgMarkup = async ({ compositionFile, compositionId, destinationDime
692
660
  }),
693
661
  },
694
662
  });
695
- if (inserted) {
696
- notifyInsertedAssets(['<Interactive.Svg>']);
697
- }
698
663
  }
699
664
  catch (error) {
700
665
  (0, NotificationCenter_1.showNotification)(`Could not add SVG: ${error instanceof Error ? error.message : String(error)}`, 4000);
@@ -720,7 +685,7 @@ const importRemoteAsset = async ({ compositionFile, compositionId, destinationDi
720
685
  fps,
721
686
  })
722
687
  : null;
723
- const inserted = await insertCompositionElement({
688
+ await insertCompositionElement({
724
689
  compositionFile,
725
690
  compositionId,
726
691
  from: (0, exports.getFromForDrop)({
@@ -739,10 +704,6 @@ const importRemoteAsset = async ({ compositionFile, compositionId, destinationDi
739
704
  }),
740
705
  },
741
706
  });
742
- if (!inserted) {
743
- return;
744
- }
745
- notifyInsertedAssets([getAssetLabel(element)]);
746
707
  }
747
708
  catch (error) {
748
709
  (0, NotificationCenter_1.showNotification)(`Could not add remote asset: ${error instanceof Error ? error.message : String(error)}`, 4000);
@@ -768,7 +729,7 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, fps, from, pr
768
729
  }),
769
730
  position: null,
770
731
  };
771
- const inserted = await insertCompositionElement({
732
+ await insertCompositionElement({
772
733
  compositionFile,
773
734
  compositionId,
774
735
  element,
@@ -778,10 +739,6 @@ const insertRemoteAudio = async ({ compositionFile, compositionId, fps, from, pr
778
739
  preferCompositionStart,
779
740
  }),
780
741
  });
781
- if (!inserted) {
782
- return;
783
- }
784
- notifyInsertedAssets([getAssetLabel(element)]);
785
742
  }
786
743
  catch (error) {
787
744
  (0, NotificationCenter_1.showNotification)(`Could not add sound effect: ${error instanceof Error ? error.message : String(error)}`, 4000);
@@ -793,7 +750,6 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
793
750
  if (assetPaths.length === 0) {
794
751
  return;
795
752
  }
796
- const insertedLabels = [];
797
753
  const unsupportedFiles = [];
798
754
  try {
799
755
  for (const assetPath of assetPaths) {
@@ -832,9 +788,7 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
832
788
  if (!inserted) {
833
789
  return;
834
790
  }
835
- insertedLabels.push(getAssetLabel(element));
836
791
  }
837
- notifyInsertedAssets(insertedLabels);
838
792
  notifyUnsupportedFiles(unsupportedFiles);
839
793
  }
840
794
  catch (error) {
@@ -844,7 +798,7 @@ const insertExistingAssets = async ({ assetPaths, compositionFile, compositionId
844
798
  exports.insertExistingAssets = insertExistingAssets;
845
799
  const insertComponent = async ({ component, compositionFile, compositionId, dropPosition, from, preferCompositionStart, }) => {
846
800
  try {
847
- const inserted = await insertCompositionElement({
801
+ await insertCompositionElement({
848
802
  compositionFile,
849
803
  compositionId,
850
804
  from: (0, exports.getFromForDrop)({
@@ -864,10 +818,6 @@ const insertComponent = async ({ component, compositionFile, compositionId, drop
864
818
  }),
865
819
  },
866
820
  });
867
- if (!inserted) {
868
- return;
869
- }
870
- (0, NotificationCenter_1.showNotification)(`Added ${getComponentLabel(component)} to source file`, 2000);
871
821
  }
872
822
  catch (error) {
873
823
  (0, NotificationCenter_1.showNotification)(`Could not add component: ${error instanceof Error ? error.message : String(error)}`, 4000);
@@ -900,7 +850,7 @@ const insertComposition = async ({ composition, compositionFile, compositionId,
900
850
  width: calculated.width,
901
851
  height: calculated.height,
902
852
  };
903
- const inserted = await insertCompositionElement({
853
+ await insertCompositionElement({
904
854
  compositionFile,
905
855
  compositionId,
906
856
  from: (0, exports.getFromForDrop)({
@@ -922,10 +872,6 @@ const insertComposition = async ({ composition, compositionFile, compositionId,
922
872
  }),
923
873
  },
924
874
  });
925
- if (!inserted) {
926
- return;
927
- }
928
- (0, NotificationCenter_1.showNotification)(`Added ${composition.compositionId} to ${compositionId}`, 2000);
929
875
  }
930
876
  catch (error) {
931
877
  (0, NotificationCenter_1.showNotification)(`Could not add composition: ${error instanceof Error ? error.message : String(error)}`, 4000);
@@ -951,9 +897,7 @@ const insertElement = async ({ compositionFile, compositionId, element, expected
951
897
  ? response.reason
952
898
  : `Element file changed: ${response.conflict.filePath}`;
953
899
  (0, NotificationCenter_1.showNotification)(`Could not add Element: ${reason}`, 4000);
954
- return;
955
900
  }
956
- (0, NotificationCenter_1.showNotification)(`Added ${element.displayName} to source file`, 2000);
957
901
  }
958
902
  catch (error) {
959
903
  (0, NotificationCenter_1.showNotification)(`Could not add Element: ${error instanceof Error ? error.message : String(error)}`, 4000);
@@ -0,0 +1,10 @@
1
+ export type KeyboardShortcut = {
2
+ readonly action: string;
3
+ readonly chords: readonly (readonly string[])[];
4
+ };
5
+ export type KeyboardShortcutGroup = {
6
+ readonly name: string;
7
+ readonly shortcuts: readonly KeyboardShortcut[];
8
+ };
9
+ export declare const keyboardShortcutGroups: readonly KeyboardShortcutGroup[];
10
+ export declare const askAIKeyboardShortcutGroup: KeyboardShortcutGroup;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.askAIKeyboardShortcutGroup = exports.keyboardShortcutGroups = void 0;
4
+ const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
5
+ const is_mac_1 = require("../helpers/is-mac");
6
+ exports.keyboardShortcutGroups = [
7
+ {
8
+ name: 'Playback',
9
+ shortcuts: [
10
+ { action: '1 second back', chords: [['Shift', '←']] },
11
+ { action: 'Previous frame', chords: [['←']] },
12
+ { action: 'Play / Pause', chords: [['Space']] },
13
+ { action: 'Next frame', chords: [['→']] },
14
+ { action: '1 second forward', chords: [['Shift', '→']] },
15
+ { action: 'Jump to beginning', chords: [['A']] },
16
+ { action: 'Jump to end', chords: [['E']] },
17
+ { action: 'Reverse playback', chords: [['J']] },
18
+ { action: 'Pause', chords: [['K']] },
19
+ { action: 'Play / Speed up', chords: [['L']] },
20
+ { action: 'Go to frame', chords: [['G']] },
21
+ {
22
+ action: 'Pause & return to playback start',
23
+ chords: [['Enter']],
24
+ },
25
+ ],
26
+ },
27
+ {
28
+ name: 'Sidebar',
29
+ shortcuts: [
30
+ {
31
+ action: 'Toggle left sidebar',
32
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'B']],
33
+ },
34
+ {
35
+ action: 'Toggle right sidebar',
36
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'J']],
37
+ },
38
+ {
39
+ action: 'Toggle both sidebars',
40
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'G']],
41
+ },
42
+ ],
43
+ },
44
+ {
45
+ name: 'View',
46
+ shortcuts: [
47
+ { action: 'Enter fullscreen', chords: [['F']] },
48
+ { action: 'Exit fullscreen', chords: [['Esc']] },
49
+ { action: 'Enable snapping', chords: [['Shift', 'M']] },
50
+ ],
51
+ },
52
+ {
53
+ name: 'Navigation',
54
+ shortcuts: [
55
+ { action: 'Previous composition', chords: [['PageUp']] },
56
+ { action: 'Next composition', chords: [['PageDown']] },
57
+ {
58
+ action: 'Render, unless a sequence or prop is selected',
59
+ chords: [['R']],
60
+ },
61
+ {
62
+ action: 'Checkerboard, unless a sequence or prop is selected',
63
+ chords: [['T']],
64
+ },
65
+ { action: 'Show keyboard shortcuts', chords: [['?']] },
66
+ {
67
+ action: 'Quick Switcher',
68
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'K']],
69
+ },
70
+ ],
71
+ },
72
+ {
73
+ name: 'Playback range',
74
+ shortcuts: [
75
+ { action: 'Set In Point', chords: [['I']] },
76
+ { action: 'Set Out Point', chords: [['O']] },
77
+ { action: 'Clear In/Out Points', chords: [['X']] },
78
+ ],
79
+ },
80
+ {
81
+ name: 'Zoom',
82
+ shortcuts: [
83
+ { action: 'Zoom in', chords: [['+']] },
84
+ { action: 'Zoom out', chords: [['-']] },
85
+ { action: 'Reset zoom', chords: [['0']] },
86
+ ],
87
+ },
88
+ {
89
+ name: 'Props Editor',
90
+ shortcuts: [
91
+ { action: 'Undo', chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'Z']] },
92
+ {
93
+ action: 'Redo',
94
+ chords: [
95
+ is_mac_1.isMac
96
+ ? [ShortcutHint_1.cmdOrCtrlCharacter, 'Shift', 'Z']
97
+ : [ShortcutHint_1.cmdOrCtrlCharacter, 'Y'],
98
+ ],
99
+ },
100
+ ],
101
+ },
102
+ {
103
+ name: 'Interactivity',
104
+ shortcuts: [
105
+ { action: 'Select range / axis lock drag', chords: [['Shift']] },
106
+ { action: 'Toggle selection', chords: [[ShortcutHint_1.cmdOrCtrlCharacter]] },
107
+ {
108
+ action: 'Select sequence rows',
109
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'A']],
110
+ },
111
+ { action: 'Select translate prop', chords: [['P']] },
112
+ { action: 'Select opacity prop', chords: [['T']] },
113
+ { action: 'Select rotate prop', chords: [['R']] },
114
+ { action: 'Select scale prop', chords: [['S']] },
115
+ {
116
+ action: 'Duplicate sequences',
117
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'D']],
118
+ },
119
+ {
120
+ action: 'Copy effects / values',
121
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'C']],
122
+ },
123
+ { action: 'Cut effects', chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'X']] },
124
+ {
125
+ action: 'Paste effects / values',
126
+ chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'V']],
127
+ },
128
+ { action: 'Delete / reset selection', chords: [['Del'], ['⌫']] },
129
+ ],
130
+ },
131
+ ];
132
+ exports.askAIKeyboardShortcutGroup = {
133
+ name: 'AI',
134
+ shortcuts: [{ action: 'Ask AI', chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'I']] }],
135
+ };
@@ -64,14 +64,10 @@ const getSelectedOutlineControlLayout = (points) => {
64
64
  const targetHalfSizeY = isSmallY ? targetHalfSize / 2 : targetHalfSize;
65
65
  const rotationHandleRadius = Math.max(targetHalfSizeX, targetHalfSizeY) * 1.5;
66
66
  const scaleEdges = ['top', 'right', 'bottom', 'left'].filter((edge) => {
67
- // Preserve one scale control per axis when opposite edge targets would overlap.
68
- if (edge === 'top') {
67
+ if (edge === 'top' || edge === 'bottom') {
69
68
  return !isTinyY;
70
69
  }
71
- if (edge === 'left') {
72
- return !isTinyX;
73
- }
74
- return true;
70
+ return !isTinyX;
75
71
  });
76
72
  const rotationCorners = ['top-left', 'top-right', 'bottom-right', 'bottom-left'].map((corner) => ({
77
73
  corner,