@remotion/studio 4.0.527 → 4.0.528

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 (258) hide show
  1. package/dist/components/AgentPrompt.js +1 -2
  2. package/dist/components/AudioWaveform.d.ts +1 -0
  3. package/dist/components/AudioWaveform.js +10 -14
  4. package/dist/components/CodeFrame.js +1 -1
  5. package/dist/components/ColorPicker/checker.d.ts +1 -1
  6. package/dist/components/CurrentAsset.js +3 -2
  7. package/dist/components/EditorRuler/Ruler.js +6 -3
  8. package/dist/components/EffectPickerModal.js +69 -43
  9. package/dist/components/ElementInstallConfirmation.js +3 -3
  10. package/dist/components/ElementLibrariesSettings.d.ts +2 -0
  11. package/dist/components/ElementLibrariesSettings.js +200 -0
  12. package/dist/components/InitialCompositionLoader.js +3 -1
  13. package/dist/components/InspectorOpenInEditor.js +13 -0
  14. package/dist/components/InspectorPanel/AlignmentControls.js +28 -9
  15. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +1 -1
  16. package/dist/components/InspectorPanel/EasingInspector.js +6 -2
  17. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -1
  18. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +1 -1
  19. package/dist/components/InspectorPanel/KeyframeInspector.js +28 -24
  20. package/dist/components/InspectorPanel/MultiSequenceNumberField.js +1 -1
  21. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -1
  22. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +30 -2
  23. package/dist/components/InspectorPanel/SequenceWrapAction.d.ts +8 -0
  24. package/dist/components/InspectorPanel/SequenceWrapAction.js +151 -0
  25. package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +2 -1
  26. package/dist/components/InspectorPanel/easing-inspector-selection.js +4 -3
  27. package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +2 -1
  28. package/dist/components/InspectorPanel/keyframe-inspector-frame.js +2 -2
  29. package/dist/components/InspectorSequenceSection.d.ts +1 -0
  30. package/dist/components/InspectorSequenceSection.js +7 -5
  31. package/dist/components/KeyboardShortcutsSettings.js +1 -1
  32. package/dist/components/Menu/styles.d.ts +2 -2
  33. package/dist/components/Modals.js +7 -6
  34. package/dist/components/ModelManager.js +10 -9
  35. package/dist/components/NewComposition/CancelButton.js +10 -4
  36. package/dist/components/NewComposition/InputDragger.d.ts +3 -1
  37. package/dist/components/NewComposition/InputDragger.js +28 -9
  38. package/dist/components/NewComposition/NewComposition.js +7 -6
  39. package/dist/components/NewComposition/RemInput.d.ts +1 -1
  40. package/dist/components/NewComposition/menu-typeahead.js +1 -1
  41. package/dist/components/Preview.js +3 -2
  42. package/dist/components/RenderModal/SchemaEditor/create-zod-values.js +1 -2
  43. package/dist/components/RenderModal/WebRenderModalPicture.js +1 -2
  44. package/dist/components/RenderQueue/CaptionQueueItem.js +14 -5
  45. package/dist/components/RenderQueue/CaptionQueueProcessor.js +30 -7
  46. package/dist/components/RenderQueue/QueueJobError.d.ts +8 -0
  47. package/dist/components/RenderQueue/QueueJobError.js +24 -0
  48. package/dist/components/RenderQueue/QueueJobErrorModal.d.ts +8 -0
  49. package/dist/components/RenderQueue/QueueJobErrorModal.js +63 -0
  50. package/dist/components/RenderQueue/RenderQueueItemCancelButton.d.ts +3 -1
  51. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +11 -4
  52. package/dist/components/RenderQueue/RenderQueueRepeat.d.ts +3 -1
  53. package/dist/components/RenderQueue/RenderQueueRepeat.js +20 -3
  54. package/dist/components/RenderQueue/VideoMattingQueueItem.js +24 -27
  55. package/dist/components/RenderQueue/VideoMattingQueueProcessor.js +68 -28
  56. package/dist/components/RenderQueue/caption-job-types.d.ts +3 -1
  57. package/dist/components/RenderQueue/context.d.ts +4 -0
  58. package/dist/components/RenderQueue/context.js +58 -8
  59. package/dist/components/RenderQueue/index.js +2 -3
  60. package/dist/components/RenderQueue/load-model-for-job.d.ts +2 -1
  61. package/dist/components/RenderQueue/load-model-for-job.js +5 -1
  62. package/dist/components/RenderQueue/video-matting-job-types.d.ts +13 -6
  63. package/dist/components/SelectedOutlineCropControls.js +2 -1
  64. package/dist/components/SelectedOutlineEditingHandles.js +9 -2
  65. package/dist/components/SelectedOutlineElement.js +9 -3
  66. package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -4
  67. package/dist/components/SelectedOutlineKeyboardControls.js +4 -22
  68. package/dist/components/SelectedOutlineOverlay.js +152 -106
  69. package/dist/components/SelectedOutlinePathPoints.d.ts +8 -0
  70. package/dist/components/SelectedOutlinePathPoints.js +433 -0
  71. package/dist/components/SelectedOutlinePolygon.js +21 -46
  72. package/dist/components/SelectedOutlineRenderer.d.ts +3 -5
  73. package/dist/components/SelectedOutlineRenderer.js +32 -136
  74. package/dist/components/SelectedOutlineTransformOriginHandle.js +3 -2
  75. package/dist/components/SelectedOutlineUvControls.js +12 -7
  76. package/dist/components/SettingsModal.js +30 -3
  77. package/dist/components/SettingsModalFooter.d.ts +1 -0
  78. package/dist/components/SettingsModalFooter.js +7 -3
  79. package/dist/components/ShowOutlinesProvider.js +1 -1
  80. package/dist/components/SkillsSettings.d.ts +0 -1
  81. package/dist/components/SkillsSettings.js +13 -14
  82. package/dist/components/Splitter/SplitterElement.js +1 -2
  83. package/dist/components/TimeValue.js +1 -1
  84. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +1 -0
  85. package/dist/components/Timeline/LoopedTimelineIndicators.js +7 -6
  86. package/dist/components/Timeline/TimelineArrayField.js +1 -1
  87. package/dist/components/Timeline/TimelineClipboardKeybindings.js +0 -1
  88. package/dist/components/Timeline/TimelineColorField.js +1 -1
  89. package/dist/components/Timeline/TimelineDragHandler.js +1 -1
  90. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  91. package/dist/components/Timeline/TimelineEffectPropItem.js +12 -5
  92. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
  93. package/dist/components/Timeline/TimelineExpandedRow.js +5 -4
  94. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
  95. package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
  96. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +1 -0
  97. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +3 -1
  98. package/dist/components/Timeline/TimelineFontFamilyField.js +12 -12
  99. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -0
  100. package/dist/components/Timeline/TimelineKeyframeControls.js +39 -28
  101. package/dist/components/Timeline/TimelineLayerChildren.js +1 -1
  102. package/dist/components/Timeline/TimelineList.js +1 -1
  103. package/dist/components/Timeline/TimelineNumberField.js +2 -4
  104. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -1
  105. package/dist/components/Timeline/TimelineSelection.d.ts +9 -9
  106. package/dist/components/Timeline/TimelineSelection.js +16 -9
  107. package/dist/components/Timeline/TimelineSequence.d.ts +3 -1
  108. package/dist/components/Timeline/TimelineSequence.js +39 -21
  109. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  110. package/dist/components/Timeline/TimelineSequenceItem.js +18 -8
  111. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +3 -0
  112. package/dist/components/Timeline/TimelineSequencePropItem.js +262 -25
  113. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +11 -13
  114. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +98 -77
  115. package/dist/components/Timeline/TimelineTextContentField.js +27 -4
  116. package/dist/components/Timeline/TimelineTimeIndicators.js +10 -5
  117. package/dist/components/Timeline/TimelineTrack.js +1 -1
  118. package/dist/components/Timeline/TimelineTrimTooltip.d.ts +11 -0
  119. package/dist/components/Timeline/TimelineTrimTooltip.js +41 -0
  120. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  121. package/dist/components/Timeline/TimelineVideoInfo.js +13 -10
  122. package/dist/components/Timeline/delete-selected-keyframe.js +22 -8
  123. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +1 -5
  124. package/dist/components/Timeline/delete-selected-timeline-item.js +7 -93
  125. package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +2 -1
  126. package/dist/components/Timeline/get-animation-item-selection-for-frame.js +7 -5
  127. package/dist/components/Timeline/get-keyframed-sequence-drag-targets.d.ts +23 -0
  128. package/dist/components/Timeline/get-keyframed-sequence-drag-targets.js +57 -0
  129. package/dist/components/Timeline/get-node-keyframes.d.ts +2 -1
  130. package/dist/components/Timeline/get-node-keyframes.js +6 -4
  131. package/dist/components/Timeline/get-playback-rate-keyframe-changes.d.ts +21 -0
  132. package/dist/components/Timeline/get-playback-rate-keyframe-changes.js +142 -0
  133. package/dist/components/Timeline/get-timeline-keyframes.d.ts +15 -2
  134. package/dist/components/Timeline/get-timeline-keyframes.js +44 -6
  135. package/dist/components/Timeline/keyframe-clipboard.js +17 -3
  136. package/dist/components/Timeline/split-selected-timeline-item.js +4 -1
  137. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  138. package/dist/components/Timeline/timeline-field-row-layout.js +1 -0
  139. package/dist/components/Timeline/use-delete-timeline-items.js +17 -11
  140. package/dist/components/Timeline/use-expanded-track-keyframe-rows.d.ts +2 -1
  141. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +3 -1
  142. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +7 -3
  143. package/dist/components/Timeline/use-timeline-keyframe-drag.js +28 -19
  144. package/dist/components/Transcription/Models.js +1 -1
  145. package/dist/components/Transcription/TranscriptionModal.js +3 -1
  146. package/dist/components/Transcription/resample-media-to-16-khz.d.ts +2 -1
  147. package/dist/components/Transcription/resample-media-to-16-khz.js +20 -2
  148. package/dist/components/UpdatesSettings.js +2 -0
  149. package/dist/components/VideoMatting/Models.js +1 -1
  150. package/dist/components/VideoMatting/VideoMattingModal.js +30 -47
  151. package/dist/components/VideoMatting/VideoMattingModalWithOptionalPackage.js +1 -1
  152. package/dist/components/WebMcp.js +22 -40
  153. package/dist/components/composition-drop-preview.js +1 -0
  154. package/dist/components/effect-drag-and-drop.d.ts +13 -5
  155. package/dist/components/effect-drag-and-drop.js +19 -4
  156. package/dist/components/get-open-in-menu-items.d.ts +2 -1
  157. package/dist/components/get-open-in-menu-items.js +17 -1
  158. package/dist/components/selected-outline-drag.d.ts +1 -6
  159. package/dist/components/selected-outline-drag.js +22 -6
  160. package/dist/components/selected-outline-geometry.d.ts +2 -18
  161. package/dist/components/selected-outline-measurement.d.ts +23 -41
  162. package/dist/components/selected-outline-measurement.js +14 -252
  163. package/dist/components/selected-outline-order.d.ts +4 -11
  164. package/dist/components/selected-outline-order.js +2 -254
  165. package/dist/components/selected-outline-snap.d.ts +1 -1
  166. package/dist/components/selected-outline-snap.js +2 -1
  167. package/dist/components/selected-outline-types.d.ts +18 -28
  168. package/dist/components/selected-outline-uv.d.ts +4 -4
  169. package/dist/components/selected-outline-uv.js +6 -111
  170. package/dist/components/sequence-props-api.js +0 -10
  171. package/dist/components/use-selected-outline-control-target.js +12 -21
  172. package/dist/components/wrap-jsx-node-api.d.ts +2 -0
  173. package/dist/components/wrap-jsx-node-api.js +13 -0
  174. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +45 -2
  175. package/dist/error-overlay/remotion-overlay/StackFrame.js +32 -3
  176. package/dist/esm/{CaptionQueueProcessor-npa6szn1.mjs → CaptionQueueProcessor-nr7hjcga.mjs} +63 -17
  177. package/dist/esm/LazyModels-ajkn7fs3.mjs +12 -0
  178. package/dist/esm/LazyModels-g1g7cf4e.mjs +12 -0
  179. package/dist/esm/{TranscriptionModal-79m5wgcj.mjs → TranscriptionModal-e18bzbkb.mjs} +15 -15
  180. package/dist/esm/{VideoMattingModal-31pew0xj.mjs → VideoMattingModal-5bz2s4rs.mjs} +47 -65
  181. package/dist/esm/{VideoMattingQueueProcessor-t1hgm2rm.mjs → VideoMattingQueueProcessor-4tkj0f4k.mjs} +69 -26
  182. package/dist/esm/{index-v4tr1bft.mjs → index-09txs1bj.mjs} +5 -0
  183. package/dist/esm/{index-n5gmcvhz.mjs → index-5ycb9e9q.mjs} +2 -4
  184. package/dist/esm/{index-5t2dwxsk.mjs → index-890dd9b3.mjs} +259 -21
  185. package/dist/esm/{index-ac5550e7.mjs → index-8nt6a0mw.mjs} +3 -3
  186. package/dist/esm/{index-614tdz2q.mjs → index-9q9w8v9p.mjs} +3 -3
  187. package/dist/esm/{index-s7qa3xbw.mjs → index-c2wabcdt.mjs} +6 -6
  188. package/dist/esm/{index-r1gr3j3a.mjs → index-dfy1t576.mjs} +50 -1
  189. package/dist/esm/{index-21hxsfaa.mjs → index-dh3zk2hv.mjs} +6 -25
  190. package/dist/esm/{index-4zen9prq.mjs → index-dpyss74p.mjs} +6563 -5485
  191. package/dist/esm/{index-9x6e1dq0.mjs → index-hqxc6tzp.mjs} +40 -6
  192. package/dist/esm/{index-9xxg6218.mjs → index-qve7mdfp.mjs} +19 -1
  193. package/dist/esm/{index-e855w59j.mjs → index-s6qya2gg.mjs} +3 -5
  194. package/dist/esm/index-t7tbt980.mjs +103 -0
  195. package/dist/esm/{index-r0ejh5sy.mjs → index-t7xnxdf8.mjs} +44 -26
  196. package/dist/esm/index-wqc43mw0.mjs +158 -0
  197. package/dist/esm/{index-ppspzgn9.mjs → index-x6r9bn12.mjs} +4026 -4761
  198. package/dist/esm/{index-vxwg66ar.mjs → index-xac20sv4.mjs} +44 -57
  199. package/dist/esm/index.mjs +4 -5
  200. package/dist/esm/internals.mjs +13 -13
  201. package/dist/esm/previewEntry.mjs +18 -15
  202. package/dist/esm/renderEntry.mjs +5 -1
  203. package/dist/helpers/calculate-timeline.d.ts +5 -1
  204. package/dist/helpers/calculate-timeline.js +1 -1
  205. package/dist/helpers/checkerboard-background.d.ts +2 -2
  206. package/dist/helpers/colors.d.ts +132 -112
  207. package/dist/helpers/colors.js +117 -95
  208. package/dist/helpers/create-folder-tree.js +2 -1
  209. package/dist/helpers/editor-guide-selection.d.ts +1 -1
  210. package/dist/helpers/editor-ruler.js +23 -12
  211. package/dist/helpers/get-connected-compositions.d.ts +6 -1
  212. package/dist/helpers/get-connected-compositions.js +1 -1
  213. package/dist/helpers/get-sequence-double-click-action.js +1 -1
  214. package/dist/helpers/get-sequence-visible-range.d.ts +1 -1
  215. package/dist/helpers/get-sequence-visible-range.js +2 -5
  216. package/dist/helpers/get-timeline-nestedness.d.ts +1 -1
  217. package/dist/helpers/get-timeline-nestedness.js +1 -1
  218. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +1 -1
  219. package/dist/helpers/get-timeline-sequence-sort-key.js +1 -1
  220. package/dist/helpers/hoverable.js +4 -4
  221. package/dist/helpers/inject-css.js +5 -7
  222. package/dist/helpers/prism-vsc-dark-plus.d.ts +1 -1
  223. package/dist/helpers/prism-vsc-dark-plus.js +52 -51
  224. package/dist/helpers/resolve-studio-color.d.ts +1 -0
  225. package/dist/helpers/resolve-studio-color.js +11 -0
  226. package/dist/helpers/studio-css-variables.d.ts +1 -0
  227. package/dist/helpers/studio-css-variables.js +105 -0
  228. package/dist/helpers/studio-pixel-ratio.d.ts +1 -0
  229. package/dist/helpers/studio-pixel-ratio.js +7 -0
  230. package/dist/helpers/timeline-node-path-key.d.ts +1 -1
  231. package/dist/helpers/timeline-node-path-key.js +2 -2
  232. package/dist/helpers/use-runtime-values.js +2 -28
  233. package/dist/hot-middleware-client/client.js +5 -3
  234. package/dist/icons/align-center-horizontal.js +2 -1
  235. package/dist/icons/align-left.js +2 -1
  236. package/dist/icons/align-right.js +2 -1
  237. package/dist/icons/{separation.d.ts → background-removal.d.ts} +1 -1
  238. package/dist/icons/background-removal.js +9 -0
  239. package/dist/icons/wrap.d.ts +4 -0
  240. package/dist/icons/wrap.js +10 -0
  241. package/dist/previewEntry.js +2 -0
  242. package/dist/renderEntry.js +2 -0
  243. package/dist/state/modals.d.ts +15 -1
  244. package/dist/state/timeline-sequence-hover.d.ts +6 -16
  245. package/dist/state/timeline-sequence-hover.js +6 -67
  246. package/package.json +20 -19
  247. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +0 -15
  248. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +0 -31
  249. package/dist/esm/LazyModels-nh3c8h9p.mjs +0 -12
  250. package/dist/esm/LazyModels-rr5v8h5y.mjs +0 -12
  251. package/dist/esm/index-cw0pnpg5.mjs +0 -50
  252. package/dist/esm/index-k426ye99.mjs +0 -139
  253. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +0 -82
  254. package/dist/helpers/get-box-quads-polyfill-internals.js +0 -2403
  255. package/dist/helpers/get-box-quads-ponyfill.d.ts +0 -10
  256. package/dist/helpers/get-box-quads-ponyfill.js +0 -23
  257. package/dist/icons/separation.js +0 -7
  258. /package/dist/esm/{resolve-composition-component-location-qrp05g62.mjs → resolve-composition-component-location-2hgf6g0a.mjs} +0 -0
@@ -60,7 +60,6 @@ const promptHeader = {
60
60
  justifyContent: 'space-between',
61
61
  };
62
62
  const skillRowContainer = {
63
- borderTop: colors_1.BORDER_WHITE_ALPHA_12,
64
63
  marginTop: 10,
65
64
  };
66
65
  const skillError = { marginTop: 10 };
@@ -87,7 +86,7 @@ const AgentPrompt = ({ availableText, promptDetails, skillId }) => {
87
86
  const renderPromptCopy = (0, react_1.useCallback)((color) => (jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: promptCopied, color: color, style: copyIcon })), [promptCopied]);
88
87
  const renderInstallCopy = (0, react_1.useCallback)((color) => (jsx_runtime_1.jsx(copy_1.CopyIcon, { copied: installCopied, color: color, style: copyIcon })), [installCopied]);
89
88
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [skillAvailable ? null : (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
90
- jsx_runtime_1.jsx("div", { style: text, children: "Install the Agent Skill first:" }), canInstallSkill && skill ? (jsx_runtime_1.jsx("div", { "aria-label": "Remotion Agent Skills", role: "list", style: skillRowContainer, children: jsx_runtime_1.jsx(SkillsSettings_1.SkillSettingsRow, { isLast: false, skill: skill }) })) : (jsx_runtime_1.jsxs("div", { style: commandField, children: [
89
+ jsx_runtime_1.jsx("div", { style: text, children: "Install the Agent Skill first:" }), canInstallSkill && skill ? (jsx_runtime_1.jsx("div", { "aria-label": "Remotion Agent Skills", role: "list", style: skillRowContainer, children: jsx_runtime_1.jsx(SkillsSettings_1.SkillSettingsRow, { skill: skill }) })) : (jsx_runtime_1.jsxs("div", { style: commandField, children: [
91
90
  jsx_runtime_1.jsx("pre", { style: code, children: installCommand }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: () => copy(installCommand, markInstallCopied), renderAction: renderInstallCopy, style: copyAction, title: "Copy command", variant: null })
92
91
  ] })), skillActionError ? (jsx_runtime_1.jsx("div", { style: skillError, children: jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: skillActionError, type: "error" }) })) : null] })), jsx_runtime_1.jsxs("div", { style: { ...promptHeader, marginTop: skillAvailable ? 0 : 16 }, children: [
93
92
  jsx_runtime_1.jsx("div", { style: text, children: skillAvailable
@@ -13,4 +13,5 @@ export declare const AudioWaveform: React.NamedExoticComponent<{
13
13
  readonly muted: boolean;
14
14
  readonly playbackRate: number;
15
15
  readonly loopDisplay: LoopDisplay | undefined;
16
+ readonly loopDisplayOffsetInFrames: number;
16
17
  }>;
@@ -40,6 +40,8 @@ const react_1 = __importStar(require("react"));
40
40
  const remotion_1 = require("remotion");
41
41
  const colors_1 = require("../helpers/colors");
42
42
  const get_timeline_max_zoom_1 = require("../helpers/get-timeline-max-zoom");
43
+ const resolve_studio_color_1 = require("../helpers/resolve-studio-color");
44
+ const studio_pixel_ratio_1 = require("../helpers/studio-pixel-ratio");
43
45
  const timeline_layout_1 = require("../helpers/timeline-layout");
44
46
  const EMPTY_PEAKS = new Float32Array(0);
45
47
  const getContainerStyle = (height) => {
@@ -66,7 +68,7 @@ const parseVolume = (volume) => {
66
68
  }
67
69
  return volume.split(',').map((v) => Number(v));
68
70
  };
69
- const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayOffsetInFrames, displayDurationInFrames, visualizationWidth, volume, doesVolumeChange, muted, playbackRate, loopDisplay, }) => {
71
+ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayOffsetInFrames, displayDurationInFrames, visualizationWidth, volume, doesVolumeChange, muted, playbackRate, loopDisplay, loopDisplayOffsetInFrames, }) => {
70
72
  const [peaks, setPeaks] = (0, react_1.useState)(null);
71
73
  const [error, setError] = (0, react_1.useState)(null);
72
74
  const vidConf = remotion_1.Internals.useUnsafeVideoConfig();
@@ -85,16 +87,9 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
85
87
  return (0, timeline_utils_1.getVisibleWaveformVolume)({
86
88
  displayDurationInFrames,
87
89
  displayOffsetInFrames,
88
- loopDisplay,
89
90
  volume: parsedVolume,
90
91
  });
91
- }, [
92
- displayDurationInFrames,
93
- displayOffsetInFrames,
94
- loopDisplay,
95
- muted,
96
- parsedVolume,
97
- ]);
92
+ }, [displayDurationInFrames, displayOffsetInFrames, muted, parsedVolume]);
98
93
  // Layout effect so that a cache hit sets the peaks synchronously and the
99
94
  // waveform is painted on the very first frame after mounting.
100
95
  (0, react_1.useLayoutEffect)(() => {
@@ -113,7 +108,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
113
108
  }
114
109
  return (0, timeline_utils_1.sliceVisibleWaveformPeaks)({
115
110
  displayDurationInFrames,
116
- displayOffsetInFrames,
111
+ displayOffsetInFrames: displayOffsetInFrames + loopDisplayOffsetInFrames,
117
112
  durationInFrames,
118
113
  fps: vidConf.fps,
119
114
  loopDisplay,
@@ -127,6 +122,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
127
122
  displayOffsetInFrames,
128
123
  durationInFrames,
129
124
  loopDisplay,
125
+ loopDisplayOffsetInFrames,
130
126
  peaks,
131
127
  playbackRate,
132
128
  startFrom,
@@ -141,7 +137,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
141
137
  if (!canvasElement) {
142
138
  return;
143
139
  }
144
- const pixelRatio = window.devicePixelRatio;
140
+ const pixelRatio = (0, studio_pixel_ratio_1.getStudioPixelRatio)();
145
141
  const h = Math.ceil(height * pixelRatio);
146
142
  const w = Math.ceil(visualizationWidth * pixelRatio);
147
143
  const drawingWidth = visualizationWidth * pixelRatio;
@@ -152,7 +148,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
152
148
  (0, timeline_utils_1.drawBars)({
153
149
  canvas: canvasElement,
154
150
  peaks: portionPeaks !== null && portionPeaks !== void 0 ? portionPeaks : EMPTY_PEAKS,
155
- color: colors_1.WHITE_ALPHA_60,
151
+ color: (0, resolve_studio_color_1.resolveStudioColor)(colors_1.WHITE_ALPHA_60, getComputedStyle(canvasElement)),
156
152
  volume: visibleVolume,
157
153
  width: drawingWidth,
158
154
  });
@@ -165,7 +161,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
165
161
  if (!volumeCanvasElement) {
166
162
  return;
167
163
  }
168
- const pixelRatio = window.devicePixelRatio;
164
+ const pixelRatio = (0, studio_pixel_ratio_1.getStudioPixelRatio)();
169
165
  const h = Math.ceil(height * pixelRatio);
170
166
  const w = Math.ceil(visualizationWidth * pixelRatio);
171
167
  const drawingWidth = visualizationWidth * pixelRatio;
@@ -195,7 +191,7 @@ const AudioWaveformInner = ({ src, height, startFrom, durationInFrames, displayO
195
191
  context.lineTo(x, y);
196
192
  }
197
193
  });
198
- context.strokeStyle = colors_1.WHITE_ALPHA_70;
194
+ context.strokeStyle = (0, resolve_studio_color_1.resolveStudioColor)(colors_1.WHITE_ALPHA_70, getComputedStyle(volumeCanvasElement));
199
195
  context.lineWidth = pixelRatio;
200
196
  context.stroke();
201
197
  }, [height, shouldRenderVolumeOverlay, visibleVolume, visualizationWidth]);
@@ -61,7 +61,7 @@ const CodeFrame = ({ source, lineNumberWidth, fontSize, horizontalMargin }) => {
61
61
  display: 'block',
62
62
  fontFamily: 'monospace',
63
63
  fontSize,
64
- color: '#9cdcfe',
64
+ color: colors_1.PRISM_VARIABLE_COLOR,
65
65
  whiteSpace: 'pre',
66
66
  tabSize: 2,
67
67
  backgroundColor: colors_1.TRANSPARENT,
@@ -1,4 +1,4 @@
1
1
  export declare const CHECKER_BACKGROUND_IMAGE: string;
2
2
  export declare const CHECKER_BACKGROUND_SIZE = "8px 8px";
3
3
  export declare const CHECKER_BACKGROUND_POSITION = "0 0, 0 4px, 4px -4px, -4px 0";
4
- export declare const CHECKER_BACKGROUND_COLOR = "#444";
4
+ export declare const CHECKER_BACKGROUND_COLOR = "var(--remotion-studio-color-picker-checker-background-color)";
@@ -16,9 +16,9 @@ const open_in_remotion_convert_1 = require("../helpers/open-in-remotion-convert"
16
16
  const render_codec_label_1 = require("../helpers/render-codec-label");
17
17
  const use_image_metadata_1 = require("../helpers/use-image-metadata");
18
18
  const use_media_metadata_1 = require("../helpers/use-media-metadata");
19
+ const background_removal_1 = require("../icons/background-removal");
19
20
  const folder_1 = require("../icons/folder");
20
21
  const remotion_convert_1 = require("../icons/remotion-convert");
21
- const separation_1 = require("../icons/separation");
22
22
  const transcription_1 = require("../icons/transcription");
23
23
  const trash_1 = require("../icons/trash");
24
24
  const modals_1 = require("../state/modals");
@@ -194,6 +194,7 @@ const AssetInfo = ({ assetName, contentSized = false, onAssetClick, readOnlyStud
194
194
  type: 'video-matting',
195
195
  src,
196
196
  displayName: fileName,
197
+ target: null,
197
198
  });
198
199
  }, [fileName, fileType, mutationsDisabled, setSelectedModal, src]);
199
200
  const canRename = onAssetClick === undefined &&
@@ -251,7 +252,7 @@ const AssetInfo = ({ assetName, contentSized = false, onAssetClick, readOnlyStud
251
252
  : '4px 0', children: jsx_runtime_1.jsx(InlineEditableTitle_1.InlineEditableTitle, { value: fileName, canRename: canRename, getInitialSelection: use_rename_static_file_1.getStaticFileRenameSelection, onClick: onAssetClick, onCommit: onRename, size: contentSized ? 'default' : 'inspector', title: assetName }) }), fileDetails.length > 0 ? (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "File", sectionId: "asset-file", children: jsx_runtime_1.jsx("div", { style: assetMetadataStyle, children: fileDetails.map((detail) => (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: detail.label, children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: detail.value }) }, detail.label))) }) })) : null, mediaSections && mediaSections.video ? (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Video", sectionId: "asset-video", children: jsx_runtime_1.jsx("div", { style: assetMetadataStyle, children: mediaSections.video.map((detail) => (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: detail.label, children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: detail.value }) }, detail.label))) }) })) : null, mediaSections && mediaSections.audio !== null ? (jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: mediaSections.audio.length > 0, label: "Audio", sectionId: "asset-audio", children: mediaSections.audio.length === 0 ? (jsx_runtime_1.jsx("div", { style: assetEmptyStateStyle, children: "None" })) : (jsx_runtime_1.jsxs("div", { style: assetMetadataStyle, children: [mediaSections.audio.map((detail) => (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: detail.label, children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: detail.value }) }, detail.label))), src ? (jsx_runtime_1.jsx(common_1.InspectorDetailRow, { label: "Average volume", children: jsx_runtime_1.jsx("span", { style: assetMetadataValueStyle, children: jsx_runtime_1.jsx(AssetAudioVolume_1.AssetAudioVolume, { src: (_d = volumeMetadata === null || volumeMetadata === void 0 ? void 0 : volumeMetadata.src) !== null && _d !== void 0 ? _d : null, waveformSampleRate: volumeMetadata
252
253
  ? Math.ceil(volumeMetadata.fps *
253
254
  get_timeline_max_zoom_1.TIMELINE_FRAME_WIDTH_AT_MAX_ZOOM)
254
- : null }, (_e = volumeMetadata === null || volumeMetadata === void 0 ? void 0 : volumeMetadata.src) !== null && _e !== void 0 ? _e : src) }) })) : null] })) })) : null, jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "asset-actions", children: jsx_runtime_1.jsxs(common_1.InspectorQuickActionsSection, { children: [fileManagerAvailable ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: fileManagerDisabled, onClick: onShowInFileManager, renderIcon: (color) => (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { color: color, style: quickActionIconStyle })), children: ["Show in ", fileManagerName] })) : null, src && (mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.hasAudioTrack) !== false ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTranscribe, renderIcon: (color) => (jsx_runtime_1.jsx(transcription_1.TranscriptionIcon, { color: color, style: quickActionIconStyle })), children: "Transcribe" })) : null, fileType === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTrackMatting, renderIcon: (color) => (jsx_runtime_1.jsx(separation_1.SeparationIcon, { color: color, style: quickActionIconStyle })), children: "Separate foreground" })) : null, src ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: false, onClick: onOpenConvert, renderIcon: (color) => (jsx_runtime_1.jsx(remotion_convert_1.RemotionConvertIcon, { color: color, style: quickActionIconStyle })), children: ["Convert",
255
+ : null }, (_e = volumeMetadata === null || volumeMetadata === void 0 ? void 0 : volumeMetadata.src) !== null && _e !== void 0 ? _e : src) }) })) : null] })) })) : null, jsx_runtime_1.jsx(CollapsibleInspectorSection_1.CollapsibleInspectorSection, { collapsible: true, label: "Actions", sectionId: "asset-actions", children: jsx_runtime_1.jsxs(common_1.InspectorQuickActionsSection, { children: [fileManagerAvailable ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: fileManagerDisabled, onClick: onShowInFileManager, renderIcon: (color) => (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { color: color, style: quickActionIconStyle })), children: ["Show in ", fileManagerName] })) : null, src && (mediaMetadata === null || mediaMetadata === void 0 ? void 0 : mediaMetadata.hasAudioTrack) !== false ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTranscribe, renderIcon: (color) => (jsx_runtime_1.jsx(transcription_1.TranscriptionIcon, { color: color, style: quickActionIconStyle })), children: "Transcribe" })) : null, fileType === 'video' ? (jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onTrackMatting, renderIcon: (color) => (jsx_runtime_1.jsx(background_removal_1.BackgroundRemovalIcon, { color: color, style: quickActionIconStyle })), children: "Remove background" })) : null, src ? (jsx_runtime_1.jsxs(common_1.InspectorQuickAction, { disabled: false, onClick: onOpenConvert, renderIcon: (color) => (jsx_runtime_1.jsx(remotion_convert_1.RemotionConvertIcon, { color: color, style: quickActionIconStyle })), children: ["Convert",
255
256
  jsx_runtime_1.jsx("svg", { "aria-hidden": "true", viewBox: "0 0 16 16", style: convertArrowStyle, children: jsx_runtime_1.jsx("path", { d: "M4 12 12 4M6 4h6v6", fill: "none", stroke: colors_1.CURRENT_COLOR, strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5" }) })
256
257
  ] })) : null, jsx_runtime_1.jsx(common_1.InspectorQuickAction, { disabled: mutationsDisabled, onClick: onDelete, renderIcon: (color) => (jsx_runtime_1.jsx(trash_1.TrashIcon, { color: color, style: quickActionIconStyle })), children: "Delete" })] }) })
257
258
  ] }));
@@ -7,6 +7,7 @@ const colors_1 = require("../../helpers/colors");
7
7
  const editor_guide_selection_1 = require("../../helpers/editor-guide-selection");
8
8
  const editor_ruler_1 = require("../../helpers/editor-ruler");
9
9
  const ruler_canvas_size_1 = require("../../helpers/ruler-canvas-size");
10
+ const studio_pixel_ratio_1 = require("../../helpers/studio-pixel-ratio");
10
11
  const editor_guides_1 = require("../../state/editor-guides");
11
12
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
12
13
  const should_clear_selection_on_pointer_down_1 = require("../Timeline/should-clear-selection-on-pointer-down");
@@ -35,6 +36,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
35
36
  orientation,
36
37
  size,
37
38
  });
39
+ const pixelRatio = (0, studio_pixel_ratio_1.getStudioPixelRatio)();
38
40
  (0, react_1.useEffect)(() => {
39
41
  (0, editor_ruler_1.drawMarkingOnRulerCanvas)({
40
42
  scale,
@@ -45,8 +47,8 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
45
47
  orientation,
46
48
  rulerCanvasRef,
47
49
  guideHighlight,
48
- canvasHeight: rulerHeight * window.devicePixelRatio,
49
- canvasWidth: rulerWidth * window.devicePixelRatio,
50
+ canvasHeight: rulerHeight * pixelRatio,
51
+ canvasWidth: rulerWidth * pixelRatio,
50
52
  });
51
53
  }, [
52
54
  scale,
@@ -59,6 +61,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
59
61
  size,
60
62
  rulerHeight,
61
63
  rulerWidth,
64
+ pixelRatio,
62
65
  ]);
63
66
  const rulerStyle = (0, react_1.useMemo)(() => ({
64
67
  position: 'absolute',
@@ -107,6 +110,6 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
107
110
  onPointerSessionStart,
108
111
  canCreateGuides,
109
112
  ]);
110
- return (jsx_runtime_1.jsx("canvas", { ref: rulerCanvasRef, width: rulerWidth * window.devicePixelRatio, height: rulerHeight * window.devicePixelRatio, style: rulerStyle, "aria-label": `${isVerticalRuler ? 'Vertical' : 'Horizontal'} ruler`, "aria-readonly": !canCreateGuides, [should_clear_selection_on_pointer_down_1.PREVENT_CLEAR_SELECTION_ON_POINTER_DOWN_ATTR]: 'true', onPointerDown: onPointerDown }));
113
+ return (jsx_runtime_1.jsx("canvas", { ref: rulerCanvasRef, width: rulerWidth * pixelRatio, height: rulerHeight * pixelRatio, style: rulerStyle, "aria-label": `${isVerticalRuler ? 'Vertical' : 'Horizontal'} ruler`, "aria-readonly": !canCreateGuides, [should_clear_selection_on_pointer_down_1.PREVENT_CLEAR_SELECTION_ON_POINTER_DOWN_ATTR]: 'true', onPointerDown: onPointerDown }));
111
114
  };
112
115
  exports.default = Ruler;
@@ -6,19 +6,17 @@ const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
7
7
  const colors_1 = require("../helpers/colors");
8
8
  const use_keybinding_1 = require("../helpers/use-keybinding");
9
- const effects_1 = require("../icons/effects");
10
9
  const external_link_1 = require("../icons/external-link");
11
10
  const modals_1 = require("../state/modals");
12
11
  const ContextMenu_1 = require("./ContextMenu");
13
12
  const effect_drag_and_drop_1 = require("./effect-drag-and-drop");
14
13
  const effect_picker_search_1 = require("./effect-picker-search");
15
- const layout_1 = require("./layout");
16
14
  const is_menu_item_1 = require("./Menu/is-menu-item");
17
15
  const DismissableModal_1 = require("./NewComposition/DismissableModal");
18
16
  const RemInput_1 = require("./NewComposition/RemInput");
19
17
  const shared_1 = require("./QuickSwitcher/shared");
20
18
  const container = {
21
- width: 400,
19
+ width: 440,
22
20
  };
23
21
  const panelStyle = {
24
22
  borderRadius: 6,
@@ -68,9 +66,13 @@ const aboutEffectsIcon = {
68
66
  width: 12,
69
67
  };
70
68
  const resultList = {
71
- height: 320,
69
+ height: 420,
70
+ display: 'grid',
71
+ gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
72
+ alignContent: 'start',
73
+ gap: 4,
72
74
  overflowY: 'auto',
73
- paddingBottom: 10,
75
+ padding: '0 12px 10px',
74
76
  };
75
77
  const noResults = {
76
78
  color: colors_1.LIGHT_TEXT,
@@ -80,40 +82,34 @@ const noResults = {
80
82
  const resultContainer = {
81
83
  cursor: 'default',
82
84
  display: 'flex',
83
- flexDirection: 'row',
84
- alignItems: 'center',
85
- paddingLeft: 16,
86
- paddingRight: 16,
87
- marginBottom: 1,
88
- marginLeft: 4,
89
- marginRight: 4,
85
+ flexDirection: 'column',
86
+ gap: 1,
87
+ padding: '3px 3px 1px',
88
+ minWidth: 0,
90
89
  borderRadius: 4,
91
90
  };
92
- const iconStyle = {
93
- width: 18,
94
- height: 18,
95
- flexShrink: 0,
96
- };
97
- const labelContainer = {
98
- flex: 1,
99
- minWidth: 0,
91
+ const previewFrame = {
92
+ width: '100%',
93
+ aspectRatio: '3 / 2',
94
+ position: 'relative',
95
+ backgroundColor: colors_1.WHITE_ALPHA_06,
96
+ borderRadius: 3,
100
97
  overflow: 'hidden',
101
- paddingTop: 5,
102
- paddingBottom: 5,
103
98
  };
104
- const label = {
105
- fontSize: shared_1.QUICK_SWITCHER_RESULT_LABEL_FONT_SIZE,
106
- overflow: 'hidden',
107
- textOverflow: 'ellipsis',
108
- whiteSpace: 'nowrap',
99
+ const preview = {
100
+ position: 'absolute',
101
+ inset: 0,
102
+ width: '100%',
103
+ height: '100%',
104
+ objectFit: 'cover',
109
105
  };
110
- const category = {
111
- color: colors_1.LIGHT_TEXT,
112
- fontSize: 11,
113
- flexShrink: 0,
106
+ const label = {
107
+ fontSize: shared_1.QUICK_SWITCHER_RESULT_LABEL_FONT_SIZE - 2,
108
+ overflowWrap: 'anywhere',
114
109
  };
115
110
  const EffectPickerResult = ({ item, selected, onSelected }) => {
116
111
  const [hovered, setHovered] = (0, react_1.useState)(false);
112
+ const [previewLoaded, setPreviewLoaded] = (0, react_1.useState)(false);
117
113
  const ref = (0, react_1.useRef)(null);
118
114
  (0, shared_1.useScrollIntoViewOnSelected)(ref, selected);
119
115
  const style = (0, react_1.useMemo)(() => {
@@ -151,7 +147,10 @@ const EffectPickerResult = ({ item, selected, onSelected }) => {
151
147
  ];
152
148
  }, [item]);
153
149
  return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: jsx_runtime_1.jsxs("div", { ref: ref, style: style, onClick: onClick, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: [
154
- jsx_runtime_1.jsx(effects_1.EffectsIcon, { color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: labelContainer, children: jsx_runtime_1.jsx("div", { style: labelStyle, children: item.label }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: category, children: item.category })
150
+ jsx_runtime_1.jsx("div", { style: previewFrame, children: jsx_runtime_1.jsx("img", { src: `https://www.remotion.dev${(0, studio_shared_1.getEffectPreviewSource)(item)}`, alt: (0, studio_shared_1.getEffectPreviewAlt)(item), style: {
151
+ ...preview,
152
+ visibility: previewLoaded ? 'visible' : 'hidden',
153
+ }, loading: "lazy", onLoad: () => setPreviewLoaded(true) }) }), jsx_runtime_1.jsx("div", { style: labelStyle, children: item.label })
155
154
  ] }) }));
156
155
  };
157
156
  const EffectPickerContent = ({ state }) => {
@@ -171,15 +170,22 @@ const EffectPickerContent = ({ state }) => {
171
170
  clientId: state.clientId,
172
171
  effect: item.effect,
173
172
  fileName: state.fileName,
174
- nodePath: state.nodePath,
173
+ nodePathInfo: state.nodePathInfo,
174
+ selectItems: state.selectItems,
175
175
  });
176
- }, [setSelectedModal, state.clientId, state.fileName, state.nodePath]);
177
- const onArrowDown = (0, react_1.useCallback)(() => {
178
- setSelectedIndex((i) => i + 1);
179
- }, []);
180
- const onArrowUp = (0, react_1.useCallback)(() => {
181
- setSelectedIndex((i) => i - 1);
182
- }, []);
176
+ }, [
177
+ setSelectedModal,
178
+ state.clientId,
179
+ state.fileName,
180
+ state.nodePathInfo,
181
+ state.selectItems,
182
+ ]);
183
+ const moveSelection = (0, react_1.useCallback)((offset) => {
184
+ if (results.length === 0) {
185
+ return;
186
+ }
187
+ setSelectedIndex((i) => (((i + offset) % results.length) + results.length) % results.length);
188
+ }, [results.length]);
183
189
  const onEnter = (0, react_1.useCallback)(() => {
184
190
  if (selectedIndexRounded === -1) {
185
191
  return;
@@ -189,7 +195,7 @@ const EffectPickerContent = ({ state }) => {
189
195
  (0, react_1.useEffect)(() => {
190
196
  const downBinding = keybindings.registerKeybinding({
191
197
  key: 'ArrowDown',
192
- callback: onArrowDown,
198
+ callback: () => moveSelection(3),
193
199
  commandCtrlKey: false,
194
200
  event: 'keydown',
195
201
  preventDefault: true,
@@ -198,7 +204,25 @@ const EffectPickerContent = ({ state }) => {
198
204
  });
199
205
  const upBinding = keybindings.registerKeybinding({
200
206
  key: 'ArrowUp',
201
- callback: onArrowUp,
207
+ callback: () => moveSelection(-3),
208
+ commandCtrlKey: false,
209
+ event: 'keydown',
210
+ preventDefault: true,
211
+ triggerIfInputFieldFocused: true,
212
+ keepRegisteredWhenNotHighestContext: false,
213
+ });
214
+ const rightBinding = keybindings.registerKeybinding({
215
+ key: 'ArrowRight',
216
+ callback: () => moveSelection(1),
217
+ commandCtrlKey: false,
218
+ event: 'keydown',
219
+ preventDefault: true,
220
+ triggerIfInputFieldFocused: true,
221
+ keepRegisteredWhenNotHighestContext: false,
222
+ });
223
+ const leftBinding = keybindings.registerKeybinding({
224
+ key: 'ArrowLeft',
225
+ callback: () => moveSelection(-1),
202
226
  commandCtrlKey: false,
203
227
  event: 'keydown',
204
228
  preventDefault: true,
@@ -217,9 +241,11 @@ const EffectPickerContent = ({ state }) => {
217
241
  return () => {
218
242
  downBinding.unregister();
219
243
  upBinding.unregister();
244
+ rightBinding.unregister();
245
+ leftBinding.unregister();
220
246
  enterBinding.unregister();
221
247
  };
222
- }, [keybindings, onArrowDown, onArrowUp, onEnter]);
248
+ }, [keybindings, moveSelection, onEnter]);
223
249
  const onTextChange = (0, react_1.useCallback)((e) => {
224
250
  setQuery(e.target.value);
225
251
  setSelectedIndex(0);
@@ -234,15 +234,15 @@ const makeSourceControlsVisible = (sourceCode) => {
234
234
  };
235
235
  const ElementLibraryAddConfirmation = ({ displayName, origin, url }) => {
236
236
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
237
- jsx_runtime_1.jsxs("dl", { style: metadataStyle, "aria-label": "Catalog details", children: [displayName === null ? null : (jsx_runtime_1.jsxs("div", { style: metadataRowStyle, children: [
237
+ jsx_runtime_1.jsxs("dl", { style: metadataStyle, "aria-label": "Element Library details", children: [displayName === null ? null : (jsx_runtime_1.jsxs("div", { style: metadataRowStyle, children: [
238
238
  jsx_runtime_1.jsx("dt", { style: metadataTermStyle, children: "Display name" }), jsx_runtime_1.jsx("dd", { style: metadataDescriptionStyle, children: displayName })
239
239
  ] })), jsx_runtime_1.jsxs("div", { style: metadataRowStyle, children: [
240
240
  jsx_runtime_1.jsx("dt", { style: metadataTermStyle, children: "Request source" }), jsx_runtime_1.jsx("dd", { style: metadataDescriptionStyle, children: origin })
241
241
  ] }), jsx_runtime_1.jsxs("div", { style: metadataRowStyle, children: [
242
- jsx_runtime_1.jsx("dt", { style: metadataTermStyle, children: "Catalog URL" }), jsx_runtime_1.jsx("dd", { style: metadataDescriptionStyle, children: jsx_runtime_1.jsx("code", { style: codeStyle, children: url }) })
242
+ jsx_runtime_1.jsx("dt", { style: metadataTermStyle, children: "Element Library URL" }), jsx_runtime_1.jsx("dd", { style: metadataDescriptionStyle, children: jsx_runtime_1.jsx("code", { style: codeStyle, children: url }) })
243
243
  ] })
244
244
  ] }), jsx_runtime_1.jsxs("div", { style: warningStyle, children: [
245
- jsx_runtime_1.jsx(ValidationMessage_1.WarningTriangle, { style: warningIconStyle }), jsx_runtime_1.jsxs("p", { style: warningDescriptionStyle, children: ["This adds the catalog to", ' ', jsx_runtime_1.jsx("strong", { style: browseElementsStyle, children: "Browse Elements" }),
245
+ jsx_runtime_1.jsx(ValidationMessage_1.WarningTriangle, { style: warningIconStyle }), jsx_runtime_1.jsxs("p", { style: warningDescriptionStyle, children: ["This adds the Element Library to", ' ', jsx_runtime_1.jsx("strong", { style: browseElementsStyle, children: "Browse Elements" }),
246
246
  " when nothing is selected on the canvas. It is saved in", ' ', jsx_runtime_1.jsx("code", { style: codeStyle, children: "remotion.config.ts" }),
247
247
  "."] })
248
248
  ] })
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const ElementLibrariesSettings: React.FC;
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ElementLibrariesSettings = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const client_id_1 = require("../helpers/client-id");
7
+ const colors_1 = require("../helpers/colors");
8
+ const browse_elements_1 = require("../icons/browse-elements");
9
+ const trash_1 = require("../icons/trash");
10
+ const ActionTooltip_1 = require("./ActionTooltip");
11
+ const Button_1 = require("./Button");
12
+ const call_api_1 = require("./call-api");
13
+ const InlineAction_1 = require("./InlineAction");
14
+ const styles_1 = require("./InspectorPanel/styles");
15
+ const RemInput_1 = require("./NewComposition/RemInput");
16
+ const ValidationMessage_1 = require("./NewComposition/ValidationMessage");
17
+ const SettingsContext_1 = require("./SettingsContext");
18
+ const Spinner_1 = require("./Spinner");
19
+ const REMOTION_ELEMENTS_URL = 'https://www.remotion.dev/elements';
20
+ const container = {
21
+ alignSelf: 'flex-start',
22
+ boxSizing: 'border-box',
23
+ flex: 1,
24
+ minWidth: 0,
25
+ width: '100%',
26
+ };
27
+ const description = {
28
+ color: colors_1.LIGHT_TEXT,
29
+ fontSize: 13,
30
+ lineHeight: 1.5,
31
+ margin: '16px 16px 12px',
32
+ };
33
+ const addLibraryHeading = {
34
+ ...styles_1.sectionHeader,
35
+ margin: '12px 0 0',
36
+ padding: '4px 16px',
37
+ };
38
+ const libraryRow = {
39
+ alignItems: 'center',
40
+ display: 'flex',
41
+ gap: 10,
42
+ minHeight: 38,
43
+ padding: '4px 16px',
44
+ };
45
+ const libraryIcon = {
46
+ flexShrink: 0,
47
+ height: 22,
48
+ width: 22,
49
+ };
50
+ const libraryDetails = {
51
+ alignItems: 'flex-start',
52
+ display: 'flex',
53
+ flex: 1,
54
+ flexDirection: 'column',
55
+ minWidth: 0,
56
+ };
57
+ const libraryName = {
58
+ fontSize: 13,
59
+ maxWidth: '100%',
60
+ overflow: 'hidden',
61
+ textOverflow: 'ellipsis',
62
+ whiteSpace: 'nowrap',
63
+ };
64
+ const libraryUrlStyle = {
65
+ cursor: 'pointer',
66
+ fontSize: 12,
67
+ maxWidth: '100%',
68
+ minWidth: 0,
69
+ outline: 'none',
70
+ overflow: 'hidden',
71
+ textDecoration: 'none',
72
+ textOverflow: 'ellipsis',
73
+ whiteSpace: 'nowrap',
74
+ };
75
+ const inputRow = {
76
+ display: 'flex',
77
+ gap: 8,
78
+ padding: '4px 16px',
79
+ };
80
+ const input = {
81
+ flex: 1,
82
+ minWidth: 0,
83
+ };
84
+ const message = {
85
+ padding: '4px 16px',
86
+ };
87
+ const trashIcon = {
88
+ height: 14,
89
+ width: 14,
90
+ };
91
+ const ElementLibrariesSettings = () => {
92
+ var _a;
93
+ const { studioRuntimeConfig } = (0, SettingsContext_1.useSettings)();
94
+ const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
95
+ const [url, setUrl] = (0, react_1.useState)('');
96
+ const [displayName, setDisplayName] = (0, react_1.useState)('');
97
+ const [busy, setBusy] = (0, react_1.useState)(null);
98
+ const [error, setError] = (0, react_1.useState)(null);
99
+ const [hoveredUrl, setHoveredUrl] = (0, react_1.useState)(null);
100
+ const libraries = ((_a = studioRuntimeConfig === null || studioRuntimeConfig === void 0 ? void 0 : studioRuntimeConfig.elementLibraries) !== null && _a !== void 0 ? _a : []).filter((library) => library.url !== REMOTION_ELEMENTS_URL);
101
+ let normalizedUrl = null;
102
+ try {
103
+ const parsedUrl = new URL(url.trim());
104
+ if (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') {
105
+ normalizedUrl = parsedUrl.href;
106
+ }
107
+ }
108
+ catch (_b) {
109
+ // Keep the Add button disabled until a valid URL is entered.
110
+ }
111
+ const duplicate = normalizedUrl === REMOTION_ELEMENTS_URL ||
112
+ libraries.some((library) => library.url === normalizedUrl);
113
+ const canSave = previewServerState.type === 'connected' && busy === null;
114
+ const addLibrary = (0, react_1.useCallback)(async () => {
115
+ if (!canSave || normalizedUrl === null || duplicate) {
116
+ return;
117
+ }
118
+ setBusy('add');
119
+ setError(null);
120
+ try {
121
+ const response = await (0, call_api_1.callApi)('/api/update-config', {
122
+ clientId: previewServerState.clientId,
123
+ updates: [
124
+ {
125
+ setter: 'addElementLibrary',
126
+ type: 'set',
127
+ value: displayName.trim()
128
+ ? { url: normalizedUrl, displayName: displayName.trim() }
129
+ : { url: normalizedUrl },
130
+ },
131
+ ],
132
+ });
133
+ if (!response.success) {
134
+ setError(response.reason);
135
+ return;
136
+ }
137
+ setUrl('');
138
+ setDisplayName('');
139
+ }
140
+ catch (err) {
141
+ setError(err.message);
142
+ }
143
+ finally {
144
+ setBusy(null);
145
+ }
146
+ }, [canSave, displayName, duplicate, normalizedUrl, previewServerState]);
147
+ const removeLibrary = (0, react_1.useCallback)(async (libraryUrl) => {
148
+ if (previewServerState.type !== 'connected' || busy !== null) {
149
+ return;
150
+ }
151
+ setBusy(libraryUrl);
152
+ setError(null);
153
+ try {
154
+ const response = await (0, call_api_1.callApi)('/api/update-config', {
155
+ clientId: previewServerState.clientId,
156
+ updates: [
157
+ {
158
+ setter: 'addElementLibrary',
159
+ type: 'delete',
160
+ value: libraryUrl,
161
+ },
162
+ ],
163
+ });
164
+ if (!response.success) {
165
+ setError(response.reason);
166
+ }
167
+ }
168
+ catch (err) {
169
+ setError(err.message);
170
+ }
171
+ finally {
172
+ setBusy(null);
173
+ }
174
+ }, [busy, previewServerState]);
175
+ const renderTrash = (0, react_1.useCallback)((color) => {
176
+ return jsx_runtime_1.jsx(trash_1.TrashIcon, { color: color, style: trashIcon });
177
+ }, []);
178
+ return (jsx_runtime_1.jsxs("section", { style: container, children: [
179
+ jsx_runtime_1.jsx("p", { style: description, children: "Add libraries to browse their elements in Studio." }), jsx_runtime_1.jsxs("div", { role: "list", "aria-label": "Element Libraries", children: [
180
+ jsx_runtime_1.jsxs("div", { role: "listitem", style: libraryRow, children: [
181
+ jsx_runtime_1.jsx(browse_elements_1.BrowseElementsIcon, { "aria-hidden": true, color: colors_1.LIGHT_TEXT, style: libraryIcon }), jsx_runtime_1.jsxs("div", { style: libraryDetails, children: [
182
+ jsx_runtime_1.jsx("div", { style: libraryName, children: "Remotion Elements" }), jsx_runtime_1.jsx("a", { href: REMOTION_ELEMENTS_URL, target: "_blank", rel: "noopener noreferrer", style: {
183
+ ...libraryUrlStyle,
184
+ color: hoveredUrl === REMOTION_ELEMENTS_URL ? colors_1.WHITE : colors_1.LIGHT_TEXT,
185
+ }, onMouseEnter: () => setHoveredUrl(REMOTION_ELEMENTS_URL), onMouseLeave: () => setHoveredUrl(null), children: REMOTION_ELEMENTS_URL.replace(/^https?:\/\//, '') })
186
+ ] })
187
+ ] }), libraries.map((library) => {
188
+ var _a, _b;
189
+ return (jsx_runtime_1.jsxs("div", { role: "listitem", style: libraryRow, children: [
190
+ jsx_runtime_1.jsx(browse_elements_1.BrowseElementsIcon, { "aria-hidden": true, color: colors_1.LIGHT_TEXT, style: libraryIcon }), jsx_runtime_1.jsxs("div", { style: libraryDetails, children: [
191
+ jsx_runtime_1.jsx("div", { style: libraryName, children: (_a = library.displayName) !== null && _a !== void 0 ? _a : new URL(library.url).host }), jsx_runtime_1.jsx("a", { href: library.url, target: "_blank", rel: "noopener noreferrer", style: {
192
+ ...libraryUrlStyle,
193
+ color: hoveredUrl === library.url ? colors_1.WHITE : colors_1.LIGHT_TEXT,
194
+ }, onMouseEnter: () => setHoveredUrl(library.url), onMouseLeave: () => setHoveredUrl(null), children: library.url.replace(/^https?:\/\//, '') })
195
+ ] }), busy === library.url ? (jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: 14 })) : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Remove", shortcut: null, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(InlineAction_1.InlineAction, { "aria-label": `Remove ${(_b = library.displayName) !== null && _b !== void 0 ? _b : library.url}`, title: "", disabled: !canSave, onClick: () => removeLibrary(library.url), renderAction: renderTrash, variant: null }) }))] }, library.url));
196
+ })] }), jsx_runtime_1.jsx("h3", { style: addLibraryHeading, children: "Add new library" }), jsx_runtime_1.jsxs("div", { style: inputRow, children: [
197
+ jsx_runtime_1.jsx(RemInput_1.RemotionInput, { "aria-label": "Element Library URL", placeholder: "https://example.com/elements", status: "ok", rightAlign: false, style: input, value: url, onChange: (event) => setUrl(event.target.value) }), jsx_runtime_1.jsx(RemInput_1.RemotionInput, { "aria-label": "Element Library name", placeholder: "Name (optional)", status: "ok", rightAlign: false, style: input, value: displayName, onChange: (event) => setDisplayName(event.target.value) })
198
+ ] }), jsx_runtime_1.jsx("div", { style: inputRow, children: jsx_runtime_1.jsx(Button_1.Button, { disabled: !canSave || normalizedUrl === null || duplicate, onClick: addLibrary, size: "compact", children: busy === 'add' ? 'Adding…' : '+ Add Element Library' }) }), duplicate ? (jsx_runtime_1.jsx("div", { style: message, children: jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", type: "warning", message: "This library is already added." }) })) : null, error ? (jsx_runtime_1.jsx("div", { style: message, children: jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", type: "error", message: error }) })) : null] }));
199
+ };
200
+ exports.ElementLibrariesSettings = ElementLibrariesSettings;
@@ -15,7 +15,9 @@ const use_static_files_1 = require("./use-static-files");
15
15
  const useSelectComposition = () => {
16
16
  const { setCompositionFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
17
17
  const { setCanvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionSetters);
18
- const setFrame = remotion_1.Internals.useTimelineSetFrame();
18
+ // A supplied frame is explicit navigation (for example, opening a nested
19
+ // composition at its sequence's frame). Plain selection does not seek.
20
+ const setFrame = remotion_1.Internals.Timeline.useTimelineSeekFrame();
19
21
  return (0, react_1.useCallback)((c, push, frame = null) => {
20
22
  var _a;
21
23
  if (push) {