@remotion/studio 4.0.520 → 4.0.521

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 (70) hide show
  1. package/dist/api/shut-down-studio.d.ts +6 -0
  2. package/dist/api/shut-down-studio.js +23 -0
  3. package/dist/components/AudioWaveform.js +10 -6
  4. package/dist/components/Canvas.js +84 -12
  5. package/dist/components/CaptionInspector.d.ts +1 -0
  6. package/dist/components/CaptionInspector.js +43 -2
  7. package/dist/components/CaptionTextEditor.js +1 -1
  8. package/dist/components/CompositionSelector.js +41 -30
  9. package/dist/components/CompositionSelectorItem.d.ts +7 -0
  10. package/dist/components/CompositionSelectorItem.js +343 -67
  11. package/dist/components/ElementInstallConfirmation.js +74 -64
  12. package/dist/components/ElementLibraryModal.js +3 -1
  13. package/dist/components/InlineCaptionInspector.js +37 -1
  14. package/dist/components/InspectorPanel/ElementLibraryButton.js +3 -18
  15. package/dist/components/InspectorSequenceSection.js +1 -4
  16. package/dist/components/Menu/MenuSubItem.js +1 -1
  17. package/dist/components/ModalContainer.d.ts +1 -0
  18. package/dist/components/ModalContainer.js +2 -2
  19. package/dist/components/ModalHeader.js +5 -1
  20. package/dist/components/QuickSwitcher/asset-search.d.ts +0 -1
  21. package/dist/components/QuickSwitcher/asset-search.js +1 -16
  22. package/dist/components/RenderButton.js +2 -2
  23. package/dist/components/RenderModal/RenderStatusModal.js +7 -1
  24. package/dist/components/RenderModal/ServerRenderModal.js +1 -1
  25. package/dist/components/RenderModal/WebRenderModal.js +1 -1
  26. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -1
  27. package/dist/components/SettingsModal.js +8 -5
  28. package/dist/components/TimeValue.js +36 -7
  29. package/dist/components/Timeline/Timeline.d.ts +1 -1
  30. package/dist/components/Timeline/Timeline.js +31 -19
  31. package/dist/components/Timeline/TimelineAssetField.d.ts +0 -1
  32. package/dist/components/Timeline/TimelineAssetField.js +16 -9
  33. package/dist/components/Timeline/TimelineCollapseToggle.js +1 -1
  34. package/dist/components/Timeline/TimelineFontWeightField.d.ts +11 -0
  35. package/dist/components/Timeline/TimelineFontWeightField.js +65 -0
  36. package/dist/components/Timeline/TimelineLayerChildren.d.ts +21 -0
  37. package/dist/components/Timeline/TimelineLayerChildren.js +129 -0
  38. package/dist/components/Timeline/TimelineNumberField.js +13 -5
  39. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +4 -0
  40. package/dist/components/Timeline/TimelineSequence.js +38 -32
  41. package/dist/components/Timeline/TimelineSequenceItem.js +2 -1
  42. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +19 -7
  43. package/dist/components/Timeline/TimelineTickFormatProvider.d.ts +8 -0
  44. package/dist/components/Timeline/TimelineTickFormatProvider.js +16 -0
  45. package/dist/components/Timeline/TimelineTimeIndicators.js +7 -3
  46. package/dist/components/Timeline/TimelineVideoInfo.js +7 -3
  47. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  48. package/dist/components/UpdateStatusContext.d.ts +5 -0
  49. package/dist/components/UpdateStatusContext.js +53 -2
  50. package/dist/components/UpdatesSettings.js +25 -4
  51. package/dist/components/WebMcp.js +26 -0
  52. package/dist/components/composition-selector-drag-data.d.ts +27 -0
  53. package/dist/components/composition-selector-drag-data.js +80 -0
  54. package/dist/components/import-assets.d.ts +2 -1
  55. package/dist/components/import-assets.js +11 -1
  56. package/dist/components/parse-caption-file.d.ts +5 -0
  57. package/dist/components/parse-caption-file.js +63 -0
  58. package/dist/esm/chunk-emw4k5b0.js +99527 -0
  59. package/dist/esm/{chunk-np6q13k5.js → chunk-vkrvnx2h.js} +5913 -4699
  60. package/dist/esm/index.mjs +23 -8
  61. package/dist/esm/internals.mjs +6729 -5366
  62. package/dist/esm/previewEntry.mjs +6779 -5416
  63. package/dist/esm/renderEntry.mjs +1 -1
  64. package/dist/helpers/get-preview-file-type.js +22 -3
  65. package/dist/helpers/inserted-element-selection.d.ts +2 -1
  66. package/dist/helpers/use-menu-structure.js +2 -2
  67. package/dist/index.d.ts +1 -0
  68. package/dist/index.js +3 -1
  69. package/dist/state/modals.d.ts +0 -2
  70. package/package.json +16 -16
@@ -6,11 +6,13 @@ const player_1 = require("@remotion/player");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const colors_1 = require("../helpers/colors");
9
+ const hoverable_1 = require("../helpers/hoverable");
9
10
  const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
10
11
  const use_keybinding_1 = require("../helpers/use-keybinding");
11
12
  const render_frame_1 = require("../state/render-frame");
12
13
  const layout_1 = require("./layout");
13
14
  const InputDragger_1 = require("./NewComposition/InputDragger");
15
+ const TimelineTickFormatProvider_1 = require("./Timeline/TimelineTickFormatProvider");
14
16
  const TimelineZoomControls_1 = require("./Timeline/TimelineZoomControls");
15
17
  const text = {
16
18
  color: colors_1.WHITE,
@@ -22,7 +24,7 @@ const text = {
22
24
  width: '100%',
23
25
  };
24
26
  const currentTimeTypography = {
25
- color: colors_1.WHITE,
27
+ color: colors_1.LIGHT_TEXT,
26
28
  display: 'inline-block',
27
29
  fontSize: 14,
28
30
  fontVariantNumeric: 'tabular-nums',
@@ -32,14 +34,34 @@ const currentTimeTypography = {
32
34
  };
33
35
  const currentTimeInputStyle = {
34
36
  ...currentTimeTypography,
35
- padding: '4px 6px 4px 0',
37
+ padding: 0,
36
38
  };
37
- const currentTimeButtonStyle = {
38
- paddingLeft: 0,
39
+ const currentTimeStack = {
40
+ display: 'flex',
41
+ flexDirection: 'column',
42
+ alignItems: 'flex-start',
43
+ lineHeight: 1,
44
+ padding: '5px 7px 5px 1px',
39
45
  transform: 'translateY(-1px)',
40
46
  };
47
+ const currentTimeButtonStyle = {
48
+ display: 'block',
49
+ padding: 0,
50
+ border: 'none',
51
+ lineHeight: '21px',
52
+ '--remotion-cli-internals-blue-hovered': colors_1.WHITE,
53
+ };
41
54
  const currentTimeSubtitle = {
42
- color: colors_1.LIGHT_TEXT,
55
+ ...(0, hoverable_1.hoverableStyle)({
56
+ idleBackground: colors_1.TRANSPARENT,
57
+ hoverBackground: colors_1.TRANSPARENT,
58
+ idleColor: colors_1.LIGHT_TEXT,
59
+ hoverColor: colors_1.WHITE,
60
+ }),
61
+ background: colors_1.TRANSPARENT,
62
+ border: 'none',
63
+ padding: 0,
64
+ cursor: 'default',
43
65
  display: 'block',
44
66
  fontFamily: 'monospace',
45
67
  fontSize: 10,
@@ -50,6 +72,10 @@ const currentTimeSubtitle = {
50
72
  };
51
73
  const TimeValue = () => {
52
74
  const frame = (0, remotion_1.useCurrentFrame)();
75
+ const { showFrames, setShowFrames } = (0, react_1.useContext)(TimelineTickFormatProvider_1.TimelineTickFormatContext);
76
+ const toggleTickFormat = (0, react_1.useCallback)(() => {
77
+ setShowFrames((previous) => !previous);
78
+ }, [setShowFrames]);
53
79
  const config = remotion_1.Internals.useUnsafeVideoConfig();
54
80
  const isStill = (0, is_current_selected_still_1.useIsStill)();
55
81
  const { seek, play, pause, toggle } = player_1.PlayerInternals.usePlayerMethods();
@@ -64,7 +90,6 @@ const TimeValue = () => {
64
90
  const formatter = (0, react_1.useCallback)((value) => {
65
91
  return config ? (0, render_frame_1.renderFrame)(Number(value), config.fps) : String(value);
66
92
  }, [config]);
67
- const formatterSubtitle = (0, react_1.useCallback)((value) => String(value), []);
68
93
  (0, react_1.useImperativeHandle)(remotion_1.Internals.timeValueRef, () => ({
69
94
  goToFrame: () => {
70
95
  var _a;
@@ -99,7 +124,11 @@ const TimeValue = () => {
99
124
  return null;
100
125
  }
101
126
  return (jsx_runtime_1.jsxs("div", { style: text, children: [
102
- jsx_runtime_1.jsx(InputDragger_1.InputDragger, { ref: ref, "aria-label": String(frame), value: frame, onTextChange: onTextChange, onValueChange: onValueChange, formatter: formatter, formatterStyle: currentTimeTypography, formatterSubtitle: formatterSubtitle, formatterSubtitleStyle: currentTimeSubtitle, buttonStyle: currentTimeButtonStyle, rightAlign: false, status: "ok", style: currentTimeInputStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(TimelineZoomControls_1.TimelineZoomControls, { sliderMaxWidth: 80 }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
127
+ jsx_runtime_1.jsxs("div", { style: currentTimeStack, children: [
128
+ jsx_runtime_1.jsx(InputDragger_1.InputDragger, { ref: ref, "aria-label": String(frame), value: frame, onTextChange: onTextChange, onValueChange: onValueChange, formatter: formatter, formatterStyle: currentTimeTypography, buttonStyle: currentTimeButtonStyle, rightAlign: false, status: "ok", style: currentTimeInputStyle }), jsx_runtime_1.jsx("button", { type: "button", className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, style: currentTimeSubtitle, onClick: toggleTickFormat, "aria-label": "Show timeline ticks as frames", "aria-pressed": showFrames, title: showFrames
129
+ ? 'Show timeline ticks as timecode'
130
+ : 'Show timeline ticks as frames', children: frame })
131
+ ] }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(TimelineZoomControls_1.TimelineZoomControls, { sliderMaxWidth: 80 }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 })
103
132
  ] }));
104
133
  };
105
134
  exports.TimeValue = TimeValue;
@@ -1,2 +1,2 @@
1
1
  import React from 'react';
2
- export declare const Timeline: React.NamedExoticComponent<{}>;
2
+ export declare const Timeline: React.FC;
@@ -69,6 +69,7 @@ const TimelineHeightContainer_1 = require("./TimelineHeightContainer");
69
69
  const TimelineInOutDragHandler_1 = require("./TimelineInOutDragHandler");
70
70
  const TimelineInOutPointer_1 = require("./TimelineInOutPointer");
71
71
  const TimelineKeyframeTracksContext_1 = require("./TimelineKeyframeTracksContext");
72
+ const TimelineLayerChildren_1 = require("./TimelineLayerChildren");
72
73
  const TimelineList_1 = require("./TimelineList");
73
74
  const TimelinePinchZoom_1 = require("./TimelinePinchZoom");
74
75
  const TimelinePlayCursorSyncer_1 = require("./TimelinePlayCursorSyncer");
@@ -76,6 +77,7 @@ const TimelineScrollable_1 = require("./TimelineScrollable");
76
77
  const TimelineSelection_1 = require("./TimelineSelection");
77
78
  const TimelineSequenceItem_1 = require("./TimelineSequenceItem");
78
79
  const TimelineSlider_1 = require("./TimelineSlider");
80
+ const TimelineTickFormatProvider_1 = require("./TimelineTickFormatProvider");
79
81
  const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
80
82
  const TimelineTracks_1 = require("./TimelineTracks");
81
83
  const TimelineVirtualization_1 = require("./TimelineVirtualization");
@@ -308,10 +310,11 @@ const TimelineInner = () => {
308
310
  return;
309
311
  }
310
312
  const matchesInsertedNodePath = (track) => track.nodePathInfo !== null &&
311
- track.nodePathInfo.sequenceSubscriptionKey.absolutePath ===
312
- pendingInsertedElementSelection.nodePath.absolutePath &&
313
- JSON.stringify(track.nodePathInfo.sequenceSubscriptionKey.nodePath) ===
314
- JSON.stringify(pendingInsertedElementSelection.nodePath.nodePath);
313
+ (pendingInsertedElementSelection.nodePath === null ||
314
+ (track.nodePathInfo.sequenceSubscriptionKey.absolutePath ===
315
+ pendingInsertedElementSelection.nodePath.absolutePath &&
316
+ JSON.stringify(track.nodePathInfo.sequenceSubscriptionKey.nodePath) ===
317
+ JSON.stringify(pendingInsertedElementSelection.nodePath.nodePath)));
315
318
  if (((_a = pendingSelectionStart.current) === null || _a === void 0 ? void 0 : _a.selection) !==
316
319
  pendingInsertedElementSelection) {
317
320
  pendingSelectionStart.current = {
@@ -342,6 +345,9 @@ const TimelineInner = () => {
342
345
  }
343
346
  selectItems([{ type: 'sequence', nodePathInfo: insertedTrack.nodePathInfo }], { reveal: true });
344
347
  (0, inserted_element_selection_1.clearInsertedElementSelection)(pendingInsertedElementSelection);
348
+ if (pendingInsertedElementSelection.notification !== null) {
349
+ (0, NotificationCenter_1.showNotification)(pendingInsertedElementSelection.notification, 3000);
350
+ }
345
351
  }, [
346
352
  canvasContent,
347
353
  fastRefreshes,
@@ -369,27 +375,33 @@ const TimelineInner = () => {
369
375
  return true;
370
376
  });
371
377
  }, [filtered]);
378
+ const { visibleTracks, value: layerChildrenValue } = (0, TimelineLayerChildren_1.useTimelineLayerChildren)(collapsed, sequences, (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null);
372
379
  const maxTimelineTracks = (0, studio_runtime_config_1.getStudioMaxTimelineTracks)();
373
380
  const shown = (0, react_1.useMemo)(() => {
374
- return maxTimelineTracks !== null && collapsed.length > maxTimelineTracks
375
- ? collapsed.slice(0, maxTimelineTracks)
376
- : collapsed;
377
- }, [collapsed, maxTimelineTracks]);
378
- const hasBeenCut = collapsed.length > shown.length;
381
+ return maxTimelineTracks !== null &&
382
+ visibleTracks.length > maxTimelineTracks
383
+ ? visibleTracks.slice(0, maxTimelineTracks)
384
+ : visibleTracks;
385
+ }, [visibleTracks, maxTimelineTracks]);
386
+ const hasBeenCut = visibleTracks.length > shown.length;
379
387
  return (jsx_runtime_1.jsxs(TimelineContextMenuArea, { children: [sequences.map((sequence) => {
380
388
  if (!(0, should_subscribe_to_sequence_props_1.shouldSubscribeToSequenceProps)(sequence, previewInteractive)) {
381
389
  return null;
382
390
  }
383
391
  return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, componentIdentity: sequence.controls.componentIdentity, schema: sequence.controls.schema, getStack: sequence.getStack, effects: sequence.effects }, sequence.id));
384
- }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: jsx_runtime_1.jsxs(TimelineVirtualization_1.TimelineVirtualizationProvider, { hasBeenCut: hasBeenCut, isStill: isStill, timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, {})) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
385
- jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
386
- jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, {}) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
387
- jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
388
- ] }), children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
389
- jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null] }) })
390
- ] })
391
- ] })) })
392
- ] }) }) })
392
+ }), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}) : null, jsx_runtime_1.jsx(TimelineLayerChildren_1.TimelineLayerChildrenProvider, { value: layerChildrenValue, children: jsx_runtime_1.jsx(TimelineKeyframeTracksContext_1.TimelineKeyframeTracksProvider, { tracks: filtered, children: jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectableItemsProvider, { timeline: shown, children: jsx_runtime_1.jsxs(TimelineVirtualization_1.TimelineVirtualizationProvider, { hasBeenCut: hasBeenCut, isStill: isStill, timeline: shown, children: [(0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectAllKeybindings, { timeline: shown })) : null, jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { children: isStill ? (jsx_runtime_1.jsx(TimelineList_1.TimelineList, {})) : (jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
393
+ jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, maxFlexerSize: null, minFlexerSize: MIN_TIMELINE_LABELS_WIDTH, maxAntiFlexerSize: null, minAntiFlexerSize: null, children: [
394
+ jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, {}) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
395
+ jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimeIndicators, {}), jsx_runtime_1.jsx(TimelineSlider_1.TimelineSlider, {})
396
+ ] }), children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
397
+ jsx_runtime_1.jsx(TimelineTracks_1.TimelineTracks, { hasBeenCut: hasBeenCut }), jsx_runtime_1.jsx(TimelinePlayCursorSyncer_1.TimelinePlayCursorSyncer, {}), jsx_runtime_1.jsx(TimelineInOutPointer_1.TimelineInOutPointer, {}), jsx_runtime_1.jsx(TimelineDragHandler_1.TimelineDragHandler, {}), (0, interactivity_enabled_1.isStudioInteractivityEnabled)() ? (jsx_runtime_1.jsx(TimelineInOutDragHandler_1.TimelineInOutDragHandler, {})) : null] }) })
398
+ ] })
399
+ ] })) })
400
+ ] }) }) }) })
393
401
  ] }));
394
402
  };
395
- exports.Timeline = react_1.default.memo(TimelineInner);
403
+ const MemoizedTimelineInner = react_1.default.memo(TimelineInner);
404
+ const Timeline = () => {
405
+ return (jsx_runtime_1.jsx(TimelineTickFormatProvider_1.TimelineTickFormatProvider, { children: jsx_runtime_1.jsx(MemoizedTimelineInner, {}) }));
406
+ };
407
+ exports.Timeline = Timeline;
@@ -4,7 +4,6 @@ import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSa
4
4
  import { type InspectorQuickActionProps } from '../InspectorPanel/common';
5
5
  export type InspectorSourceAction = InspectorQuickActionProps;
6
6
  type AssetSelectionContextValue = {
7
- readonly initialQuery: string;
8
7
  readonly getSourceAction: (src: string) => InspectorSourceAction | null;
9
8
  readonly sourceAction: InspectorSourceAction | null;
10
9
  };
@@ -32,9 +32,13 @@ const standaloneSourceActionStyle = {
32
32
  minWidth: 0,
33
33
  width: 'auto',
34
34
  };
35
+ const assetTypeToAccept = {
36
+ audio: 'audio/*',
37
+ video: 'video/*',
38
+ image: 'image/*',
39
+ };
35
40
  exports.AssetSelectionContext = (0, react_1.createContext)({
36
41
  getSourceAction: () => null,
37
- initialQuery: '',
38
42
  sourceAction: null,
39
43
  });
40
44
  const toFileToken = (name) => {
@@ -50,14 +54,14 @@ const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragV
50
54
  }
51
55
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
52
56
  const staticFiles = (0, use_static_files_1.useStaticFiles)();
53
- const { getSourceAction, initialQuery, sourceAction } = (0, react_1.useContext)(exports.AssetSelectionContext);
57
+ const { getSourceAction, sourceAction } = (0, react_1.useContext)(exports.AssetSelectionContext);
58
+ const { assetType } = field.fieldSchema;
59
+ const initialQuery = assetType ? `type:${assetType} ` : '';
54
60
  const inlineSourceAction = (0, react_1.useMemo)(() => {
55
- if (field.key !== 'src') {
56
- return null;
61
+ if (typeof effectiveValue === 'string') {
62
+ return getSourceAction(effectiveValue);
57
63
  }
58
- return typeof effectiveValue === 'string'
59
- ? getSourceAction(effectiveValue)
60
- : sourceAction;
64
+ return field.key === 'src' ? sourceAction : null;
61
65
  }, [effectiveValue, field.key, getSourceAction, sourceAction]);
62
66
  const onSelect = (0, react_1.useCallback)((assetName, previewValue) => {
63
67
  const sourceValue = (0, exports.toFileToken)(assetName);
@@ -70,7 +74,10 @@ const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragV
70
74
  });
71
75
  }, [propStatus.codeValue, onDragValueChange, onSave, onDragEnd]);
72
76
  const selectFile = (0, react_1.useCallback)(async () => {
73
- const [file] = await (0, import_assets_1.pickFilesToImport)({ multiple: false });
77
+ const [file] = await (0, import_assets_1.pickFilesToImport)({
78
+ multiple: false,
79
+ accept: assetType ? assetTypeToAccept[assetType] : null,
80
+ });
74
81
  if (!file) {
75
82
  return;
76
83
  }
@@ -94,7 +101,7 @@ const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragV
94
101
  catch (error) {
95
102
  (0, NotificationCenter_1.showNotification)(`Could not upload asset: ${error instanceof Error ? error.message : String(error)}`, 4000);
96
103
  }
97
- }, [onSelect, staticFiles]);
104
+ }, [assetType, onSelect, staticFiles]);
98
105
  const openAssetSelection = (0, react_1.useCallback)(() => {
99
106
  setSelectedModal({
100
107
  type: 'quick-switcher',
@@ -10,7 +10,7 @@ const container = {
10
10
  alignItems: 'center',
11
11
  };
12
12
  const Icon = ({ color, ...props }) => {
13
- return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 8 10", ...props, style: { height: 10, width: 8 }, children: jsx_runtime_1.jsx("path", { d: "M 0 0 L 8 5 L 0 10 z", fill: color }) }));
13
+ return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 8 10", ...props, style: { height: 8, width: 6.4 }, children: jsx_runtime_1.jsx("path", { d: "M 0 0 L 8 5 L 0 10 z", fill: color }) }));
14
14
  };
15
15
  const TimelineCollapseToggle = ({ collapsed, color }) => {
16
16
  return (jsx_runtime_1.jsx("div", { style: collapsed ? container : { ...container, transform: 'rotate(90deg)' }, children: jsx_runtime_1.jsx(Icon, { color: color }) }));
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { CanUpdateSequencePropStatusStatic } from 'remotion';
3
+ import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSave } from '../../helpers/timeline-layout';
4
+ export declare const TimelineFontWeightField: React.FC<{
5
+ readonly field: SchemaFieldInfo;
6
+ readonly propStatus: CanUpdateSequencePropStatusStatic;
7
+ readonly effectiveValue: unknown;
8
+ readonly onSave: TimelineFieldOnSave;
9
+ readonly onDragValueChange: TimelineFieldOnDragValueChange;
10
+ readonly onDragEnd: () => void;
11
+ }>;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineFontWeightField = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const ComboBox_1 = require("../NewComposition/ComboBox");
7
+ const RemInput_1 = require("../NewComposition/RemInput");
8
+ const timeline_field_utils_1 = require("./timeline-field-utils");
9
+ const TimelineNumberField_1 = require("./TimelineNumberField");
10
+ const FONT_WEIGHT_KEYWORDS = ['normal', 'bold', 'bolder', 'lighter'];
11
+ const TimelineFontWeightField = ({ field, propStatus, effectiveValue, onSave, onDragValueChange, onDragEnd, }) => {
12
+ var _a;
13
+ const { fieldSchema } = field;
14
+ if (fieldSchema.type !== 'font-weight') {
15
+ throw new Error('TimelineFontWeightField rendered for non-font-weight field');
16
+ }
17
+ const sourceValue = (_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : fieldSchema.default;
18
+ const currentValue = effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : sourceValue;
19
+ const onSelectKeyword = (0, react_1.useCallback)((newValue) => {
20
+ if (newValue === propStatus.codeValue) {
21
+ return;
22
+ }
23
+ onDragValueChange(newValue);
24
+ onSave(newValue).finally(onDragEnd);
25
+ }, [onDragEnd, onDragValueChange, onSave, propStatus.codeValue]);
26
+ const keywordItems = (0, react_1.useMemo)(() => {
27
+ return FONT_WEIGHT_KEYWORDS.map((keyword) => ({
28
+ type: 'item',
29
+ id: keyword,
30
+ value: keyword,
31
+ label: keyword,
32
+ onClick: () => onSelectKeyword(keyword),
33
+ keyHint: null,
34
+ leftItem: null,
35
+ subMenu: null,
36
+ quickSwitcherLabel: null,
37
+ disabled: false,
38
+ }));
39
+ }, [onSelectKeyword]);
40
+ if (typeof sourceValue === 'number') {
41
+ return (jsx_runtime_1.jsx(TimelineNumberField_1.TimelineNumberField, { effectiveValue: currentValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }));
42
+ }
43
+ if (FONT_WEIGHT_KEYWORDS.includes(sourceValue)) {
44
+ return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "small", title: field.key, selectedId: String(currentValue), values: keywordItems }));
45
+ }
46
+ return (jsx_runtime_1.jsx(RemInput_1.RemotionInput, { status: "ok", rightAlign: false, small: true, defaultValue: String(currentValue !== null && currentValue !== void 0 ? currentValue : ''), onBlur: (event) => {
47
+ const newValue = event.currentTarget.value;
48
+ if (newValue === propStatus.codeValue) {
49
+ onDragEnd();
50
+ return;
51
+ }
52
+ onSave(newValue).finally(onDragEnd);
53
+ }, onChange: (event) => onDragValueChange(event.currentTarget.value), onDoubleClick: (event) => event.stopPropagation(), onKeyDown: (event) => {
54
+ var _a;
55
+ if (event.key === 'Enter') {
56
+ event.currentTarget.blur();
57
+ }
58
+ if (event.key === 'Escape') {
59
+ event.currentTarget.value = String((_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : '');
60
+ onDragEnd();
61
+ event.currentTarget.blur();
62
+ }
63
+ }, style: { ...timeline_field_utils_1.draggerStyle, boxSizing: 'border-box' } }, String(sourceValue)));
64
+ };
65
+ exports.TimelineFontWeightField = TimelineFontWeightField;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import type { TSequence } from 'remotion';
3
+ import type { TimelineTrackData } from '../../helpers/get-timeline-sequence-sort-key';
4
+ export declare const TimelineLayerChildrenProvider: React.Provider<{
5
+ readonly collapsed: Record<string, boolean>;
6
+ readonly keys: Map<string, string>;
7
+ readonly parents: Set<string>;
8
+ readonly toggle: (key: string) => void;
9
+ } | null>;
10
+ export declare const useTimelineLayerChildren: (tracks: TimelineTrackData[], sequences: TSequence[], compositionId: string | null) => {
11
+ visibleTracks: TimelineTrackData[];
12
+ value: {
13
+ collapsed: Record<string, boolean>;
14
+ keys: Map<string, string>;
15
+ parents: Set<string>;
16
+ toggle: (key: string) => void;
17
+ };
18
+ };
19
+ export declare const TimelineLayerChildrenToggle: React.FC<{
20
+ readonly sequence: TSequence;
21
+ }>;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimelineLayerChildrenToggle = exports.useTimelineLayerChildren = exports.TimelineLayerChildrenProvider = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const colors_1 = require("../../helpers/colors");
7
+ const hoverable_1 = require("../../helpers/hoverable");
8
+ const persist_boolean_map_1 = require("../../helpers/persist-boolean-map");
9
+ const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
10
+ const TimelineCollapseToggle_1 = require("./TimelineCollapseToggle");
11
+ const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
12
+ const STORAGE_KEY = 'remotion.editor.collapsedLayerChildren.v1';
13
+ const TimelineLayerChildrenContext = (0, react_1.createContext)(null);
14
+ exports.TimelineLayerChildrenProvider = TimelineLayerChildrenContext.Provider;
15
+ const useTimelineLayerChildren = (tracks, sequences, compositionId) => {
16
+ const [collapsed, setCollapsed] = (0, react_1.useState)(() => {
17
+ var _a;
18
+ try {
19
+ const parsed = JSON.parse((_a = window.localStorage.getItem(STORAGE_KEY)) !== null && _a !== void 0 ? _a : '{}');
20
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
21
+ return {};
22
+ }
23
+ return Object.fromEntries(Object.entries(parsed).filter(([, storedValue]) => storedValue === true));
24
+ }
25
+ catch (_b) {
26
+ return {};
27
+ }
28
+ });
29
+ const toggle = (0, react_1.useCallback)((key) => {
30
+ setCollapsed((previous) => {
31
+ const next = (0, persist_boolean_map_1.toggleBooleanMapKey)(previous, key);
32
+ try {
33
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
34
+ }
35
+ catch (_a) {
36
+ // Keep the control usable when storage is unavailable.
37
+ }
38
+ return next;
39
+ });
40
+ }, []);
41
+ const hierarchy = (0, react_1.useMemo)(() => {
42
+ var _a;
43
+ var _b, _c;
44
+ const byId = new Map(sequences.map((sequence) => [sequence.id, sequence]));
45
+ const siblingIndices = new Map();
46
+ const siblingCounts = new Map();
47
+ for (const sequence of sequences) {
48
+ const index = (_b = siblingCounts.get(sequence.parent)) !== null && _b !== void 0 ? _b : 0;
49
+ siblingIndices.set(sequence.id, index);
50
+ siblingCounts.set(sequence.parent, index + 1);
51
+ }
52
+ const keys = new Map();
53
+ const parents = new Set();
54
+ const ancestors = new Map();
55
+ for (const track of tracks) {
56
+ const parentIds = [];
57
+ let { parent } = track.sequence;
58
+ while (parent !== null && !parentIds.includes(parent)) {
59
+ parentIds.push(parent);
60
+ parents.add(parent);
61
+ parent = (_c = (_a = byId.get(parent)) === null || _a === void 0 ? void 0 : _a.parent) !== null && _c !== void 0 ? _c : null;
62
+ }
63
+ ancestors.set(track.sequence.id, parentIds);
64
+ // Source identity survives remounts. For layers without source metadata,
65
+ // use the structural position instead of the ephemeral sequence ID.
66
+ const identity = track.nodePathInfo
67
+ ? ['source', (0, timeline_node_path_key_1.timelineNodePathInfoToKey)(track.nodePathInfo)]
68
+ : [
69
+ 'position',
70
+ ...[...parentIds]
71
+ .reverse()
72
+ .concat(track.sequence.id)
73
+ .map((id) => siblingIndices.get(id)),
74
+ ];
75
+ keys.set(track.sequence.id, JSON.stringify([compositionId, identity]));
76
+ }
77
+ return { keys, parents, ancestors };
78
+ }, [compositionId, sequences, tracks]);
79
+ const visibleTracks = (0, react_1.useMemo)(() => tracks.filter((track) => {
80
+ var _a;
81
+ return !((_a = hierarchy.ancestors.get(track.sequence.id)) !== null && _a !== void 0 ? _a : []).some((id) => {
82
+ const key = hierarchy.keys.get(id);
83
+ return key !== undefined && collapsed[key];
84
+ });
85
+ }), [hierarchy, collapsed, tracks]);
86
+ const value = (0, react_1.useMemo)(() => ({
87
+ collapsed,
88
+ keys: hierarchy.keys,
89
+ parents: hierarchy.parents,
90
+ toggle,
91
+ }), [collapsed, hierarchy, toggle]);
92
+ return { visibleTracks, value };
93
+ };
94
+ exports.useTimelineLayerChildren = useTimelineLayerChildren;
95
+ const TimelineLayerChildrenToggle = ({ sequence }) => {
96
+ const context = (0, react_1.useContext)(TimelineLayerChildrenContext);
97
+ const key = context === null || context === void 0 ? void 0 : context.keys.get(sequence.id);
98
+ const isCollapsed = key !== undefined && Boolean(context === null || context === void 0 ? void 0 : context.collapsed[key]);
99
+ const onClick = (0, react_1.useCallback)((event) => {
100
+ event.stopPropagation();
101
+ if (key !== undefined) {
102
+ context === null || context === void 0 ? void 0 : context.toggle(key);
103
+ }
104
+ }, [context, key]);
105
+ const stopPropagation = (0, react_1.useCallback)((event) => event.stopPropagation(), []);
106
+ if (!(context === null || context === void 0 ? void 0 : context.parents.has(sequence.id)) || key === undefined) {
107
+ return jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {});
108
+ }
109
+ const label = `${isCollapsed ? 'Expand' : 'Collapse'} children of ${sequence.displayName}`;
110
+ return (jsx_runtime_1.jsx("button", { type: "button", className: `${hoverable_1.HOVERABLE_CLASS_NAME} ${hoverable_1.FOCUS_VISIBLE_ONLY_CLASS_NAME}`, "aria-label": label, "aria-expanded": !isCollapsed, title: label, onClick: onClick, onPointerDown: stopPropagation, onDoubleClick: stopPropagation, style: {
111
+ ...(0, hoverable_1.hoverableStyle)({
112
+ idleBackground: colors_1.TRANSPARENT,
113
+ hoverBackground: colors_1.TRANSPARENT,
114
+ idleColor: colors_1.LIGHT_TEXT,
115
+ hoverColor: colors_1.WHITE,
116
+ }),
117
+ border: 'none',
118
+ padding: 0,
119
+ cursor: 'default',
120
+ display: 'flex',
121
+ alignItems: 'center',
122
+ justifyContent: 'center',
123
+ width: 12,
124
+ height: 16,
125
+ marginRight: 0,
126
+ flexShrink: 0,
127
+ }, children: jsx_runtime_1.jsx(TimelineCollapseToggle_1.TimelineCollapseToggle, { collapsed: isCollapsed, color: "currentColor" }) }));
128
+ };
129
+ exports.TimelineLayerChildrenToggle = TimelineLayerChildrenToggle;
@@ -35,8 +35,12 @@ const TimelineNumberField = ({ field, effectiveValue, onSave, onDragValueChange,
35
35
  }
36
36
  }, [onSave, propStatus]);
37
37
  const configuredStep = field.fieldSchema.type === 'number' ? field.fieldSchema.step : undefined;
38
- const step = configuredStep !== null && configuredStep !== void 0 ? configuredStep : 1;
39
- const allowStepMismatch = field.group === 'crop' ||
38
+ const currentValue = dragValue !== null && dragValue !== void 0 ? dragValue : effectiveValue;
39
+ const step = field.fieldSchema.type === 'font-weight' && currentValue % 100 === 0
40
+ ? 100
41
+ : (configuredStep !== null && configuredStep !== void 0 ? configuredStep : 1);
42
+ const allowStepMismatch = field.fieldSchema.type === 'font-weight' ||
43
+ field.group === 'crop' ||
40
44
  ('kind' in field && field.kind === 'effect-field');
41
45
  const formatter = (0, react_1.useCallback)((v) => {
42
46
  return (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
@@ -44,10 +48,14 @@ const TimelineNumberField = ({ field, effectiveValue, onSave, onDragValueChange,
44
48
  value: v,
45
49
  });
46
50
  }, [field.fieldSchema]);
47
- return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : effectiveValue, buttonStyle: timeline_field_utils_1.leftAlignedDraggerStyle, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: field.fieldSchema.type === 'number'
51
+ return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: currentValue, buttonStyle: timeline_field_utils_1.leftAlignedDraggerStyle, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: field.fieldSchema.type === 'number'
48
52
  ? ((_a = field.fieldSchema.min) !== null && _a !== void 0 ? _a : -Infinity)
49
- : -Infinity, max: field.fieldSchema.type === 'number'
53
+ : field.fieldSchema.type === 'font-weight'
54
+ ? 1
55
+ : -Infinity, max: field.fieldSchema.type === 'number'
50
56
  ? ((_b = field.fieldSchema.max) !== null && _b !== void 0 ? _b : Infinity)
51
- : Infinity, step: step, formatter: formatter, rightAlign: false, allowStepMismatch: allowStepMismatch }));
57
+ : field.fieldSchema.type === 'font-weight'
58
+ ? 1000
59
+ : Infinity, step: step, dragSensitivity: field.fieldSchema.type === 'font-weight' && step === 100 ? 0.1 : 1, formatter: formatter, rightAlign: false, allowStepMismatch: allowStepMismatch }));
52
60
  };
53
61
  exports.TimelineNumberField = TimelineNumberField;
@@ -7,6 +7,7 @@ const TimelineBooleanField_1 = require("./TimelineBooleanField");
7
7
  const TimelineColorField_1 = require("./TimelineColorField");
8
8
  const TimelineEnumField_1 = require("./TimelineEnumField");
9
9
  const TimelineFontFamilyField_1 = require("./TimelineFontFamilyField");
10
+ const TimelineFontWeightField_1 = require("./TimelineFontWeightField");
10
11
  const TimelineNumberField_1 = require("./TimelineNumberField");
11
12
  const TimelineRotationField_1 = require("./TimelineRotationField");
12
13
  const TimelineScaleField_1 = require("./TimelineScaleField");
@@ -67,6 +68,9 @@ const TimelinePrimitiveFieldValue = ({ field, onSave, onDragValueChange, onDragE
67
68
  if (field.typeName === 'font-family') {
68
69
  return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineFontFamilyField_1.TimelineFontFamilyField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
69
70
  }
71
+ if (field.typeName === 'font-weight') {
72
+ return (jsx_runtime_1.jsx("span", { style: inlineWrapper, children: jsx_runtime_1.jsx(TimelineFontWeightField_1.TimelineFontWeightField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
73
+ }
70
74
  if (field.typeName === 'asset') {
71
75
  return (jsx_runtime_1.jsx("span", { style: assetInlineWrapper, children: jsx_runtime_1.jsx(TimelineAssetField_1.TimelineAssetField, { effectiveValue: effectiveValue, field: field, onDragEnd: onDragEnd, onDragValueChange: onDragValueChange, onSave: onSave, propStatus: propStatus }) }));
72
76
  }