@remotion/studio 4.0.494 → 4.0.496

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 (125) hide show
  1. package/dist/api/get-static-files.d.ts +1 -1
  2. package/dist/components/AssetFileIcon.d.ts +7 -0
  3. package/dist/components/AssetFileIcon.js +24 -0
  4. package/dist/components/AssetSelectorItem.js +20 -14
  5. package/dist/components/Canvas.js +191 -36
  6. package/dist/components/CompositionSelectorItem.js +20 -31
  7. package/dist/components/CurrentAsset.d.ts +1 -0
  8. package/dist/components/CurrentAsset.js +21 -4
  9. package/dist/components/Editor.js +2 -4
  10. package/dist/components/InlineCompositionName.js +1 -1
  11. package/dist/components/InlineEditableTitle.d.ts +1 -0
  12. package/dist/components/InlineEditableTitle.js +56 -11
  13. package/dist/components/InspectorInfoHeader.d.ts +2 -0
  14. package/dist/components/InspectorInfoHeader.js +16 -4
  15. package/dist/components/InspectorLocationCopy.js +2 -2
  16. package/dist/components/InspectorPanel/AssetInspector.d.ts +4 -0
  17. package/dist/components/InspectorPanel/AssetInspector.js +11 -0
  18. package/dist/components/InspectorPanel/{DefaultInspector.d.ts → CompositionInspector.d.ts} +2 -2
  19. package/dist/components/InspectorPanel/CompositionInspector.js +114 -0
  20. package/dist/components/InspectorPanel/CompositionInspectorHeader.d.ts +1 -0
  21. package/dist/components/{CurrentComposition.js → InspectorPanel/CompositionInspectorHeader.js} +26 -21
  22. package/dist/components/InspectorPanel/{CompositionDimensions.d.ts → CompositionMetadata.d.ts} +1 -1
  23. package/dist/components/InspectorPanel/{CompositionDimensions.js → CompositionMetadata.js} +17 -8
  24. package/dist/components/InspectorPanel/ConnectedCompositionsSection.js +2 -2
  25. package/dist/components/InspectorPanel/EasingInspector.js +4 -6
  26. package/dist/components/InspectorPanel/KeyframeInspector.js +7 -8
  27. package/dist/components/InspectorPanel/KeyframeSettings.js +1 -1
  28. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +28 -3
  29. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +34 -1
  30. package/dist/components/InspectorPanel/common.d.ts +12 -2
  31. package/dist/components/InspectorPanel/common.js +45 -22
  32. package/dist/components/InspectorPanel/styles.d.ts +5 -6
  33. package/dist/components/InspectorPanel/styles.js +13 -39
  34. package/dist/components/InspectorPanel/use-composition-actions.d.ts +8 -0
  35. package/dist/components/InspectorPanel/use-composition-actions.js +114 -0
  36. package/dist/components/InspectorPanel.js +11 -2
  37. package/dist/components/InspectorSequenceSection.d.ts +0 -1
  38. package/dist/components/InspectorSequenceSection.js +20 -49
  39. package/dist/components/InspectorSourceLocation.d.ts +1 -0
  40. package/dist/components/InspectorSourceLocation.js +5 -1
  41. package/dist/components/Modals.js +2 -1
  42. package/dist/components/NewComposition/ComboBox.d.ts +2 -1
  43. package/dist/components/NewComposition/ComboBox.js +32 -7
  44. package/dist/components/NewComposition/InputDragger.d.ts +6 -0
  45. package/dist/components/NewComposition/InputDragger.js +26 -13
  46. package/dist/components/NewComposition/NewComposition.js +8 -1
  47. package/dist/components/NewComposition/ValidationMessage.d.ts +1 -1
  48. package/dist/components/PlaybackRateSelector.js +3 -3
  49. package/dist/components/Preview.js +15 -7
  50. package/dist/components/PreviewToolbar.js +3 -3
  51. package/dist/components/RenderButton.d.ts +1 -0
  52. package/dist/components/RenderButton.js +51 -7
  53. package/dist/components/RenderModal/RenderModalOutputName.js +34 -1
  54. package/dist/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +1 -1
  55. package/dist/components/RenderModal/SchemaEditor/ZodEnumEditor.js +1 -1
  56. package/dist/components/RenderModal/SchemaEditor/ZodStaticFileEditor.js +1 -1
  57. package/dist/components/SelectedOutlineOverlay.js +1 -0
  58. package/dist/components/SizeSelector.js +3 -3
  59. package/dist/components/SvgImportDialog.d.ts +7 -0
  60. package/dist/components/SvgImportDialog.js +103 -0
  61. package/dist/components/Timeline/Timeline.js +1 -0
  62. package/dist/components/Timeline/TimelineAssetField.js +1 -1
  63. package/dist/components/Timeline/TimelineClipboardKeybindings.js +8 -1
  64. package/dist/components/Timeline/TimelineEnumField.js +1 -1
  65. package/dist/components/Timeline/TimelineFieldLabel.js +3 -3
  66. package/dist/components/Timeline/TimelineKeyframeControls.js +26 -6
  67. package/dist/components/Timeline/TimelineList.js +9 -4
  68. package/dist/components/Timeline/TimelineRowChrome.js +10 -2
  69. package/dist/components/Timeline/TimelineRowLayoutContext.d.ts +3 -0
  70. package/dist/components/Timeline/TimelineRowLayoutContext.js +6 -0
  71. package/dist/components/Timeline/TimelineSequenceItem.d.ts +2 -1
  72. package/dist/components/Timeline/TimelineSequenceItem.js +19 -11
  73. package/dist/components/Timeline/nest-timeline-tracks.d.ts +8 -0
  74. package/dist/components/Timeline/nest-timeline-tracks.js +25 -0
  75. package/dist/components/Timeline/timeline-scroll-logic.d.ts +8 -4
  76. package/dist/components/Timeline/timeline-scroll-logic.js +29 -15
  77. package/dist/components/import-assets.d.ts +17 -1
  78. package/dist/components/import-assets.js +96 -11
  79. package/dist/components/layout.d.ts +2 -0
  80. package/dist/components/layout.js +3 -1
  81. package/dist/components/open-in-new-window.d.ts +2 -0
  82. package/dist/components/open-in-new-window.js +28 -0
  83. package/dist/components/selected-outline-measurement.d.ts +2 -1
  84. package/dist/components/selected-outline-measurement.js +3 -1
  85. package/dist/esm/{chunk-tdncqycp.js → chunk-0v4n7nkh.js} +8463 -7092
  86. package/dist/esm/internals.mjs +8463 -7092
  87. package/dist/esm/previewEntry.mjs +8613 -7242
  88. package/dist/esm/renderEntry.mjs +1 -1
  89. package/dist/helpers/client-id.js +2 -1
  90. package/dist/helpers/clipboard-figma.d.ts +4 -0
  91. package/dist/helpers/clipboard-figma.js +41 -0
  92. package/dist/helpers/clipboard-images.d.ts +10 -0
  93. package/dist/helpers/clipboard-images.js +77 -0
  94. package/dist/helpers/clipboard-svg.d.ts +3 -0
  95. package/dist/helpers/clipboard-svg.js +47 -0
  96. package/dist/helpers/get-effective-translation.d.ts +2 -1
  97. package/dist/helpers/get-effective-translation.js +15 -7
  98. package/dist/helpers/get-preview-file-type.d.ts +1 -1
  99. package/dist/helpers/get-preview-file-type.js +5 -1
  100. package/dist/helpers/inject-css.js +11 -0
  101. package/dist/helpers/studio-fit-padding.d.ts +41 -0
  102. package/dist/helpers/studio-fit-padding.js +64 -0
  103. package/dist/helpers/use-image-metadata.d.ts +8 -0
  104. package/dist/helpers/use-image-metadata.js +82 -0
  105. package/dist/helpers/use-studio-canvas-dimensions.js +2 -2
  106. package/dist/icons/audio.d.ts +3 -0
  107. package/dist/icons/audio.js +3 -1
  108. package/dist/icons/font.d.ts +4 -0
  109. package/dist/icons/font.js +8 -0
  110. package/dist/icons/frame.d.ts +3 -1
  111. package/dist/icons/frame.js +1 -1
  112. package/dist/icons/json.d.ts +4 -0
  113. package/dist/icons/json.js +8 -0
  114. package/dist/icons/magnet.js +1 -1
  115. package/dist/icons/scissors.d.ts +5 -0
  116. package/dist/icons/scissors.js +8 -0
  117. package/dist/icons/solid.d.ts +5 -0
  118. package/dist/icons/solid.js +8 -0
  119. package/dist/icons/video.d.ts +3 -0
  120. package/dist/icons/video.js +5 -1
  121. package/dist/state/modals.d.ts +8 -1
  122. package/dist/state/timeline-zoom.js +12 -11
  123. package/package.json +11 -11
  124. package/dist/components/CurrentComposition.d.ts +0 -2
  125. package/dist/components/InspectorPanel/DefaultInspector.js +0 -97
@@ -9,6 +9,7 @@ const ErrorLoader_1 = require("../error-overlay/remotion-overlay/ErrorLoader");
9
9
  const checkerboard_background_1 = require("../helpers/checkerboard-background");
10
10
  const colors_1 = require("../helpers/colors");
11
11
  const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
12
+ const studio_fit_padding_1 = require("../helpers/studio-fit-padding");
12
13
  const checkerboard_1 = require("../state/checkerboard");
13
14
  const is_menu_item_1 = require("./Menu/is-menu-item");
14
15
  const RenderPreview_1 = require("./RenderPreview");
@@ -78,13 +79,20 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
78
79
  scale: 1,
79
80
  };
80
81
  }
81
- return player_1.PlayerInternals.calculateCanvasTransformation({
82
- canvasSize,
83
- compositionHeight: contentDimensions.height,
84
- compositionWidth: contentDimensions.width,
85
- previewSize: previewSize.size,
86
- });
87
- }, [canvasSize, contentDimensions, previewSize.size]);
82
+ return canvasContent.type === 'composition'
83
+ ? (0, studio_fit_padding_1.calculateStudioCanvasTransformation)({
84
+ canvasSize,
85
+ compositionHeight: contentDimensions.height,
86
+ compositionWidth: contentDimensions.width,
87
+ previewSize: previewSize.size,
88
+ })
89
+ : player_1.PlayerInternals.calculateCanvasTransformation({
90
+ canvasSize,
91
+ compositionHeight: contentDimensions.height,
92
+ compositionWidth: contentDimensions.width,
93
+ previewSize: previewSize.size,
94
+ });
95
+ }, [canvasContent.type, canvasSize, contentDimensions, previewSize.size]);
88
96
  const outer = (0, react_1.useMemo)(() => {
89
97
  return {
90
98
  width: contentDimensions === 'none' ? '100%' : contentDimensions.width * scale,
@@ -26,7 +26,7 @@ const SizeSelector_1 = require("./SizeSelector");
26
26
  const SnappingToggle_1 = require("./SnappingToggle");
27
27
  const TimelineZoomControls_1 = require("./Timeline/TimelineZoomControls");
28
28
  const TimelineInOutToggle_1 = require("./TimelineInOutToggle");
29
- const TOOLBAR_HEIGHT = 50;
29
+ const TOOLBAR_HEIGHT = 40;
30
30
  const container = {
31
31
  display: 'flex',
32
32
  justifyContent: 'center',
@@ -64,7 +64,7 @@ const scrollIndicatorRight = {
64
64
  };
65
65
  const sideContainer = {
66
66
  width: 300,
67
- height: 36,
67
+ height: 30,
68
68
  display: 'flex',
69
69
  flexDirection: 'row',
70
70
  alignItems: 'center',
@@ -169,7 +169,7 @@ const PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
169
169
  jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(CheckboardToggle_1.CheckboardToggle, {}) }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(OutlineToggle_1.OutlineToggle, { disabled: readOnlyStudio }) }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(SnappingToggle_1.SnappingToggle, { disabled: readOnlyStudio }) })
170
170
  ] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), canvasContent && isFullscreenSupported ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(FullscreenToggle_1.FullScreenToggle, {}) })) : null, jsx_runtime_1.jsx(layout_1.Flex, {}), isMobileLayout && (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
171
171
  jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(SizeSelector_1.SizeSelector, {}) }), isStill || isVideoComposition ? (jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate }) })) : null] })), jsx_runtime_1.jsxs("div", { style: sideContainer, children: [
172
- jsx_runtime_1.jsx(layout_1.Flex, {}), !isMobileLayout && jsx_runtime_1.jsx(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RenderButton_1.RenderButton, { readOnlyStudio: readOnlyStudio }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
172
+ jsx_runtime_1.jsx(layout_1.Flex, {}), !isMobileLayout && jsx_runtime_1.jsx(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 2 }), jsx_runtime_1.jsx(PreviewToolbarControl, { children: jsx_runtime_1.jsx(RenderButton_1.RenderButton, { readOnlyStudio: readOnlyStudio, size: "compact" }) }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1.5 })
173
173
  ] }), jsx_runtime_1.jsx(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate }), jsx_runtime_1.jsx(PlaybackRatePersistor_1.PlaybackRatePersistor, {}), jsx_runtime_1.jsx("div", { ref: rightScrollIndicatorRef, style: scrollIndicatorRight })
174
174
  ] }));
175
175
  };
@@ -2,4 +2,5 @@ import React from 'react';
2
2
  export type RenderType = 'server-render' | 'client-render' | 'render-command';
3
3
  export declare const RenderButton: React.FC<{
4
4
  readonly readOnlyStudio: boolean;
5
+ readonly size?: 'default' | 'compact';
5
6
  }>;
@@ -65,9 +65,47 @@ const dropdownTriggerStyle = {
65
65
  const mainButtonContent = {
66
66
  paddingLeft: 4,
67
67
  paddingRight: 6,
68
+ minWidth: 0,
68
69
  };
69
70
  const label = {
71
+ color: 'inherit',
72
+ fontFamily: 'inherit',
70
73
  fontSize: 14,
74
+ lineHeight: '21px',
75
+ minWidth: 0,
76
+ overflow: 'hidden',
77
+ textOverflow: 'ellipsis',
78
+ whiteSpace: 'nowrap',
79
+ };
80
+ const compactSplitButtonSegmentHeight = layout_1.COMPACT_CONTROL_ROW_HEIGHT;
81
+ const compactMainButtonStyle = {
82
+ ...mainButtonStyle,
83
+ boxSizing: 'border-box',
84
+ height: compactSplitButtonSegmentHeight,
85
+ paddingLeft: 6,
86
+ paddingRight: 6,
87
+ paddingTop: 6,
88
+ paddingBottom: 6,
89
+ fontSize: 12,
90
+ };
91
+ const compactDropdownTriggerStyle = {
92
+ ...dropdownTriggerStyle,
93
+ boxSizing: 'border-box',
94
+ height: compactSplitButtonSegmentHeight,
95
+ paddingLeft: 5,
96
+ paddingRight: 5,
97
+ paddingTop: 6,
98
+ paddingBottom: 6,
99
+ };
100
+ const compactMainButtonContent = {
101
+ ...mainButtonContent,
102
+ paddingLeft: 2,
103
+ paddingRight: 4,
104
+ };
105
+ const compactLabel = {
106
+ ...label,
107
+ fontSize: 12,
108
+ lineHeight: '16px',
71
109
  };
72
110
  const RENDER_TYPE_STORAGE_KEY = 'remotion.renderType';
73
111
  const getInitialRenderType = (readOnlyStudio) => {
@@ -85,7 +123,7 @@ const getInitialRenderType = (readOnlyStudio) => {
85
123
  }
86
124
  return 'server-render';
87
125
  };
88
- const RenderButton = ({ readOnlyStudio, }) => {
126
+ const RenderButton = ({ readOnlyStudio, size: controlSize = 'default' }) => {
89
127
  const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
90
128
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
91
129
  const [preferredRenderType, setPreferredRenderType] = (0, react_1.useState)(() => getInitialRenderType(readOnlyStudio));
@@ -153,11 +191,12 @@ const RenderButton = ({ readOnlyStudio, }) => {
153
191
  const iconStyle = (0, react_1.useMemo)(() => {
154
192
  return {
155
193
  style: {
156
- height: 16,
194
+ height: controlSize === 'compact' ? 14 : 16,
157
195
  color: colors_1.CURRENT_COLOR,
196
+ flexShrink: 0,
158
197
  },
159
198
  };
160
- }, []);
199
+ }, [controlSize]);
161
200
  const video = remotion_1.Internals.useVideo();
162
201
  const { getCurrentFrame } = player_1.PlayerInternals.usePlayer();
163
202
  const { props } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
@@ -385,10 +424,11 @@ const RenderButton = ({ readOnlyStudio, }) => {
385
424
  return {
386
425
  ...splitButtonContainer,
387
426
  borderColor: colors_1.BLACK_ALPHA_60,
427
+ borderRadius: controlSize === 'compact' ? 0 : 4,
388
428
  opacity: 1,
389
429
  cursor: 'pointer',
390
430
  };
391
- }, []);
431
+ }, [controlSize]);
392
432
  const renderLabel = renderType === 'server-render'
393
433
  ? 'Render'
394
434
  : renderType === 'render-command'
@@ -399,9 +439,13 @@ const RenderButton = ({ readOnlyStudio, }) => {
399
439
  }
400
440
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
401
441
  jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-server", disabled: !canServerRender, onClick: () => openServerRenderModal(false), type: "button" }), ' ', jsx_runtime_1.jsx("button", { style: { display: 'none' }, id: "render-modal-button-client", onClick: openClientRenderModal, type: "button" }), jsx_runtime_1.jsxs("div", { ref: containerRef, style: containerStyle, title: tooltip, children: [
402
- jsx_runtime_1.jsx("button", { type: "button", style: mainButtonStyle, onClick: onClick, id: "render-modal-button", children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", style: mainButtonContent, children: [
403
- jsx_runtime_1.jsx(render_1.ThinRenderIcon, { fill: colors_1.CURRENT_COLOR_LOWERCASE, svgProps: iconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("span", { style: label, children: renderLabel })
404
- ] }) }), jsx_runtime_1.jsx("div", { style: dividerStyle }), jsx_runtime_1.jsx("button", { ref: dropdownRef, type: "button", style: dropdownTriggerStyle, className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, onPointerDown: onPointerDown, onClick: onClickDropdown, children: jsx_runtime_1.jsx(caret_1.CaretDown, {}) })
442
+ jsx_runtime_1.jsx("button", { type: "button", style: controlSize === 'compact' ? compactMainButtonStyle : mainButtonStyle, onClick: onClick, id: "render-modal-button", children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", style: controlSize === 'compact'
443
+ ? compactMainButtonContent
444
+ : mainButtonContent, children: [
445
+ jsx_runtime_1.jsx(render_1.ThinRenderIcon, { fill: colors_1.CURRENT_COLOR_LOWERCASE, svgProps: iconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: controlSize === 'compact' ? 0.75 : 1 }), jsx_runtime_1.jsx("span", { style: controlSize === 'compact' ? compactLabel : label, children: renderLabel })
446
+ ] }) }), jsx_runtime_1.jsx("div", { style: dividerStyle }), jsx_runtime_1.jsx("button", { ref: dropdownRef, type: "button", style: controlSize === 'compact'
447
+ ? compactDropdownTriggerStyle
448
+ : dropdownTriggerStyle, className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, onPointerDown: onPointerDown, onClick: onClickDropdown, children: jsx_runtime_1.jsx(caret_1.CaretDown, {}) })
405
449
  ] }), portalStyle
406
450
  ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: onHideDropdown, onEscape: onHideDropdown, children: jsx_runtime_1.jsx("div", { style: portalStyle, onPointerDown: onMenuPointerDown, children: jsx_runtime_1.jsx(MenuContent_1.MenuContent, { onNextMenu: () => { }, onPreviousMenu: () => { }, values: dropdownValues, onHide: onHideDropdown, leaveLeftSpace: false, preselectIndex: dropdownValues.findIndex((v) => v.id === renderType), topItemCanBeUnselected: false, fixedHeight: derivedMaxHeight }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
407
451
  : null] }));
@@ -2,17 +2,50 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RenderModalOutputName = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const colors_1 = require("../../helpers/colors");
7
+ const get_file_manager_name_1 = require("../../helpers/get-file-manager-name");
8
+ const folder_1 = require("../../icons/folder");
9
+ const InlineAction_1 = require("../InlineAction");
5
10
  const layout_1 = require("../layout");
6
11
  const RemInput_1 = require("../NewComposition/RemInput");
7
12
  const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
13
+ const NotificationCenter_1 = require("../Notifications/NotificationCenter");
14
+ const actions_1 = require("../RenderQueue/actions");
8
15
  const layout_2 = require("./layout");
16
+ const existsMessageStyle = {
17
+ display: 'inline-flex',
18
+ alignItems: 'center',
19
+ minWidth: 0,
20
+ fontFamily: 'sans-serif',
21
+ fontSize: 13,
22
+ lineHeight: '18px',
23
+ color: colors_1.WHITE,
24
+ whiteSpace: 'nowrap',
25
+ };
26
+ const openIconStyle = {
27
+ width: 12,
28
+ height: 12,
29
+ flexShrink: 0,
30
+ };
9
31
  const RenderModalOutputName = ({ existence, inputStyle, outName, onValueChange, validationMessage, label: labelText, }) => {
32
+ const openExistingOutput = (0, react_1.useCallback)(() => {
33
+ (0, actions_1.openInFileExplorer)({ directory: outName }).catch((err) => {
34
+ (0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
35
+ });
36
+ }, [outName]);
37
+ const renderOpenIcon = (0, react_1.useCallback)((color) => {
38
+ return jsx_runtime_1.jsx(folder_1.ExpandedFolderIconSolid, { style: openIconStyle, color: color });
39
+ }, []);
40
+ const fileManagerName = (0, get_file_manager_name_1.getFileManagerName)(window.remotion_fileSystemPlatform);
10
41
  return (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
11
42
  jsx_runtime_1.jsx(layout_1.Column, { children: jsx_runtime_1.jsx("div", { style: layout_2.label, children: labelText }) }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsxs("div", { children: [
12
43
  jsx_runtime_1.jsx(RemInput_1.RemotionInput, { status: validationMessage ? 'error' : existence ? 'warning' : 'ok', style: inputStyle, type: "text", value: outName, onChange: onValueChange, rightAlign: true }), validationMessage ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
13
44
  jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: validationMessage, type: 'error' })
14
45
  ] })) : existence ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
15
- jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: "Will be overwritten", type: 'warning' })
46
+ jsx_runtime_1.jsx(layout_1.Spacing, { y: 1, block: true }), jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: jsx_runtime_1.jsxs("span", { style: existsMessageStyle, children: [
47
+ jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: openExistingOutput, renderAction: renderOpenIcon, title: `Open in ${fileManagerName}` }),
48
+ "Exists, will be overwritten"] }), type: 'warning' })
16
49
  ] })) : null] }) })
17
50
  ] }));
18
51
  };
@@ -47,7 +47,7 @@ const ZodDiscriminatedUnionEditor = ({ schema, setValue, value, mayPad, jsonPath
47
47
  return {
48
48
  discriminator,
49
49
  markup: (jsx_runtime_1.jsxs(Fieldset_1.Fieldset, { shouldPad: mayPad, children: [
50
- jsx_runtime_1.jsx(SchemaLabel_1.SchemaLabel, { handleClick: null, jsonPath: [...jsonPath, discriminator], onRemove: onRemove, suffix: null, valid: zodValidation.success }), jsx_runtime_1.jsx(ComboBox_1.Combobox, { title: "Select type", values: comboBoxValues, selectedId: value[discriminator], small: true })
50
+ jsx_runtime_1.jsx(SchemaLabel_1.SchemaLabel, { handleClick: null, jsonPath: [...jsonPath, discriminator], onRemove: onRemove, suffix: null, valid: zodValidation.success }), jsx_runtime_1.jsx(ComboBox_1.Combobox, { title: "Select type", values: comboBoxValues, selectedId: value[discriminator], size: "small" })
51
51
  ] }, 'replacement')),
52
52
  };
53
53
  }, [
@@ -39,7 +39,7 @@ const ZodEnumEditor = ({ schema, jsonPath, setValue, value, onRemove }) => {
39
39
  }, [enumValues, onChange, value]);
40
40
  const zodValidation = (0, react_1.useMemo)(() => (0, zod_schema_type_1.zodSafeParse)(schema, value), [schema, value]);
41
41
  return (jsx_runtime_1.jsxs(Fieldset_1.Fieldset, { shouldPad: true, children: [
42
- jsx_runtime_1.jsx(SchemaLabel_1.SchemaLabel, { handleClick: null, jsonPath: jsonPath, onRemove: onRemove, valid: zodValidation.success, suffix: null }), jsx_runtime_1.jsx("div", { style: isRoot ? undefined : container, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: comboBoxValues, selectedId: value, title: value, small: true }) }), jsx_runtime_1.jsx(ZodFieldValidation_1.ZodFieldValidation, { path: jsonPath, zodValidation: zodValidation })
42
+ jsx_runtime_1.jsx(SchemaLabel_1.SchemaLabel, { handleClick: null, jsonPath: jsonPath, onRemove: onRemove, valid: zodValidation.success, suffix: null }), jsx_runtime_1.jsx("div", { style: isRoot ? undefined : container, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: comboBoxValues, selectedId: value, title: value, size: "small" }) }), jsx_runtime_1.jsx(ZodFieldValidation_1.ZodFieldValidation, { path: jsonPath, zodValidation: zodValidation })
43
43
  ] }));
44
44
  };
45
45
  exports.ZodEnumEditor = ZodEnumEditor;
@@ -38,7 +38,7 @@ const ZodStaticFileEditor = ({ schema, jsonPath, setValue, value, onRemove, mayP
38
38
  });
39
39
  }, [onChange, staticFiles, value]);
40
40
  return (jsx_runtime_1.jsxs(Fieldset_1.Fieldset, { shouldPad: mayPad, children: [
41
- jsx_runtime_1.jsx(SchemaLabel_1.SchemaLabel, { handleClick: null, jsonPath: jsonPath, onRemove: onRemove, valid: zodValidation.success, suffix: null }), jsx_runtime_1.jsx("div", { style: isRoot ? undefined : container, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: comboBoxValues, selectedId: value, title: value, small: true }) }), jsx_runtime_1.jsx(ZodFieldValidation_1.ZodFieldValidation, { path: jsonPath, zodValidation: zodValidation })
41
+ jsx_runtime_1.jsx(SchemaLabel_1.SchemaLabel, { handleClick: null, jsonPath: jsonPath, onRemove: onRemove, valid: zodValidation.success, suffix: null }), jsx_runtime_1.jsx("div", { style: isRoot ? undefined : container, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: comboBoxValues, selectedId: value, title: value, size: "small" }) }), jsx_runtime_1.jsx(ZodFieldValidation_1.ZodFieldValidation, { path: jsonPath, zodValidation: zodValidation })
42
42
  ] }));
43
43
  };
44
44
  exports.ZodStaticFileEditor = ZodStaticFileEditor;
@@ -411,6 +411,7 @@ const SelectedOutlineOverlay = ({ compositionHeight, compositionWidth, scale, tr
411
411
  sequences,
412
412
  overrideIdsToNodePaths: overrideIdToNodePathMappings,
413
413
  compositions,
414
+ timelinePosition,
414
415
  }).map(({ key, keyframeDisplayOffset, nodePathInfo, sequence }) => {
415
416
  var _a, _b, _c, _d, _e, _f;
416
417
  if (sequence.refForOutline === null) {
@@ -46,7 +46,7 @@ const getPreviewSizeLabel = (previewSize) => {
46
46
  };
47
47
  exports.getPreviewSizeLabel = getPreviewSizeLabel;
48
48
  const accessibilityLabel = 'Preview Size';
49
- const comboStyle = { width: 80 };
49
+ const comboStyle = { width: 64 };
50
50
  const getUniqueSizes = (size) => {
51
51
  const customPreviewSizes = [size, ...commonPreviewSizes];
52
52
  const uniqueSizes = [];
@@ -72,7 +72,7 @@ const SizeSelector = () => {
72
72
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
73
73
  const style = (0, react_1.useMemo)(() => {
74
74
  return {
75
- padding: ControlButton_1.CONTROL_BUTTON_PADDING,
75
+ padding: ControlButton_1.CONTROL_BUTTON_PADDING - 2,
76
76
  };
77
77
  }, []);
78
78
  const zoomable = (0, react_1.useMemo)(() => {
@@ -114,6 +114,6 @@ const SizeSelector = () => {
114
114
  if (!zoomable) {
115
115
  return null;
116
116
  }
117
- return (jsx_runtime_1.jsx("div", { style: style, "aria-label": accessibilityLabel, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { title: accessibilityLabel, style: comboStyle, selectedId: String(size.size), values: items }) }));
117
+ return (jsx_runtime_1.jsx("div", { style: style, "aria-label": accessibilityLabel, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "compact", title: accessibilityLabel, style: comboStyle, selectedId: String(size.size), values: items }) }));
118
118
  };
119
119
  exports.SizeSelector = SizeSelector;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { SvgImportDialogState } from '../state/modals';
3
+ export type SvgImportMode = 'image' | 'inline';
4
+ export declare const useSvgImportDialog: () => () => Promise<SvgImportMode | null>;
5
+ export declare const SvgImportDialog: React.FC<{
6
+ readonly state: SvgImportDialogState;
7
+ }>;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SvgImportDialog = exports.useSvgImportDialog = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const modals_1 = require("../state/modals");
7
+ const Button_1 = require("./Button");
8
+ const layout_1 = require("./layout");
9
+ const ModalButton_1 = require("./ModalButton");
10
+ const ModalContainer_1 = require("./ModalContainer");
11
+ const ModalFooter_1 = require("./ModalFooter");
12
+ const ModalHeader_1 = require("./ModalHeader");
13
+ const content = {
14
+ padding: 16,
15
+ fontFamily: 'inherit',
16
+ fontSize: 14,
17
+ lineHeight: 1.4,
18
+ color: 'inherit',
19
+ minWidth: 560,
20
+ };
21
+ const inlineCode = {
22
+ fontFamily: 'monospace',
23
+ fontSize: 'inherit',
24
+ lineHeight: 'inherit',
25
+ color: 'inherit',
26
+ };
27
+ const useSvgImportDialog = () => {
28
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
29
+ return (0, react_1.useCallback)(() => {
30
+ return new Promise((resolve) => {
31
+ let settled = false;
32
+ const settle = (result) => {
33
+ if (settled) {
34
+ return;
35
+ }
36
+ settled = true;
37
+ resolve(result);
38
+ };
39
+ setSelectedModal({
40
+ type: 'svg-import-dialog',
41
+ id: String(Math.random()),
42
+ onImage: () => settle('image'),
43
+ onInline: () => settle('inline'),
44
+ onDismiss: () => settle(null),
45
+ });
46
+ });
47
+ }, [setSelectedModal]);
48
+ };
49
+ exports.useSvgImportDialog = useSvgImportDialog;
50
+ const SvgImportDialog = ({ state }) => {
51
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
52
+ const settledRef = (0, react_1.useRef)(false);
53
+ const closeCurrentModal = (0, react_1.useCallback)(() => {
54
+ setSelectedModal((modal) => (modal === null || modal === void 0 ? void 0 : modal.type) === 'svg-import-dialog' && modal.id === state.id
55
+ ? null
56
+ : modal);
57
+ }, [setSelectedModal, state.id]);
58
+ const settle = (0, react_1.useCallback)((result) => {
59
+ if (settledRef.current) {
60
+ return;
61
+ }
62
+ settledRef.current = true;
63
+ closeCurrentModal();
64
+ if (result === 'image') {
65
+ state.onImage();
66
+ }
67
+ else if (result === 'inline') {
68
+ state.onInline();
69
+ }
70
+ else {
71
+ state.onDismiss();
72
+ }
73
+ }, [closeCurrentModal, state]);
74
+ (0, react_1.useEffect)(() => {
75
+ return () => {
76
+ if (settledRef.current) {
77
+ return;
78
+ }
79
+ settledRef.current = true;
80
+ state.onDismiss();
81
+ };
82
+ }, [state]);
83
+ const onImage = (0, react_1.useCallback)(() => {
84
+ settle('image');
85
+ }, [settle]);
86
+ const onInline = (0, react_1.useCallback)(() => {
87
+ settle('inline');
88
+ }, [settle]);
89
+ const onDismiss = (0, react_1.useCallback)(() => {
90
+ settle(null);
91
+ }, [settle]);
92
+ return (jsx_runtime_1.jsxs(ModalContainer_1.ModalContainer, { onOutsideClick: onDismiss, onEscape: onDismiss, children: [
93
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: "Add .svg", onClose: onDismiss }), jsx_runtime_1.jsx("div", { style: content, children: "Do you want to import this as an image or as inline SVG?" }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", children: [
94
+ jsx_runtime_1.jsx(layout_1.Flex, {}), jsx_runtime_1.jsxs(Button_1.Button, { onClick: onImage, children: ["Add to ",
95
+ jsx_runtime_1.jsx("code", { style: inlineCode, children: "public" }),
96
+ " and import as", ' ', jsx_runtime_1.jsx("code", { style: inlineCode, children: '<CanvasImage>' })
97
+ ] }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsxs(ModalButton_1.ModalButton, { onClick: onInline, autoFocus: true, children: ["Import as inline ",
98
+ jsx_runtime_1.jsx("code", { style: inlineCode, children: '<svg>' })
99
+ ] })
100
+ ] }) })
101
+ ] }));
102
+ };
103
+ exports.SvgImportDialog = SvgImportDialog;
@@ -166,6 +166,7 @@ const TimelineContextMenuArea = ({ children }) => {
166
166
  compositionId: currentCompositionId,
167
167
  destinationDimensions: null,
168
168
  dropPosition: null,
169
+ svgImportMode: 'image',
169
170
  });
170
171
  }
171
172
  finally {
@@ -109,7 +109,7 @@ const TimelineStaticFileAssetField = ({ propStatus, effectiveValue, onSave, onDr
109
109
  },
110
110
  ];
111
111
  }, [current, onSelect, staticFiles, upload]);
112
- return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { small: true, title: current, selectedId: current, values: items, style: comboboxStyle }));
112
+ return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "small", title: current, selectedId: current, values: items, style: comboboxStyle }));
113
113
  };
114
114
  const TimelineAssetField = (props) => {
115
115
  var _a;
@@ -5,6 +5,9 @@ const studio_shared_1 = require("@remotion/studio-shared");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const client_id_1 = require("../../helpers/client-id");
8
+ const clipboard_figma_1 = require("../../helpers/clipboard-figma");
9
+ const clipboard_images_1 = require("../../helpers/clipboard-images");
10
+ const clipboard_svg_1 = require("../../helpers/clipboard-svg");
8
11
  const use_keybinding_1 = require("../../helpers/use-keybinding");
9
12
  const call_api_1 = require("../call-api");
10
13
  const ConfirmationDialog_1 = require("../ConfirmationDialog");
@@ -567,7 +570,11 @@ const TimelineClipboardKeybindings = () => {
567
570
  return;
568
571
  }
569
572
  const { selectedItems } = currentSelection.current;
570
- if (selectedItems.length === 0 || e.clipboardData === null) {
573
+ if (selectedItems.length === 0 ||
574
+ e.clipboardData === null ||
575
+ (0, clipboard_figma_1.hasClipboardFigmaPayload)(e.clipboardData) ||
576
+ (0, clipboard_images_1.hasClipboardImage)(e.clipboardData) ||
577
+ (0, clipboard_svg_1.hasClipboardSvgMarkup)(e.clipboardData)) {
571
578
  return;
572
579
  }
573
580
  e.preventDefault();
@@ -37,6 +37,6 @@ const TimelineEnumField = ({ field, propStatus, effectiveValue, onSave, onDragVa
37
37
  disabled: false,
38
38
  }));
39
39
  }, [variantKeys, onSelect]);
40
- return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { small: true, title: field.key, selectedId: current, values: items, style: comboboxStyle }));
40
+ return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "small", title: field.key, selectedId: current, values: items, style: comboboxStyle }));
41
41
  };
42
42
  exports.TimelineEnumField = TimelineEnumField;
@@ -19,13 +19,13 @@ const fieldNameBase = {
19
19
  minWidth: 0,
20
20
  };
21
21
  const TimelineFieldLabel = ({ rowDepth, selected, label, stacked = false }) => {
22
- const { basePadding } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
22
+ const { basePadding, highlightSelectedLabel } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
23
23
  const labelRowStyle = (0, react_1.useMemo)(() => ({
24
24
  ...(0, timeline_field_row_layout_1.getTimelineFieldLabelRowStyle)(rowDepth, basePadding),
25
- ...(0, TimelineSelection_1.getTimelineSelectedLabelStyle)(selected, true),
25
+ ...(0, TimelineSelection_1.getTimelineSelectedLabelStyle)(selected && highlightSelectedLabel, true),
26
26
  ...(stacked ? { flex: `0 0 ${timeline_layout_1.SCHEMA_FIELD_ROW_HEIGHT}px` } : null),
27
27
  alignSelf: 'stretch',
28
- }), [basePadding, rowDepth, selected, stacked]);
28
+ }), [basePadding, highlightSelectedLabel, rowDepth, selected, stacked]);
29
29
  const fieldNameStyle = (0, react_1.useMemo)(() => ({
30
30
  ...fieldNameBase,
31
31
  color: (0, TimelineSelection_1.getTimelineColor)(selected, true),
@@ -18,6 +18,9 @@ const TimelineKeyframeDiamondIcon_1 = require("./TimelineKeyframeDiamondIcon");
18
18
  const TimelineKeyframeTracksContext_1 = require("./TimelineKeyframeTracksContext");
19
19
  const TimelineSelection_1 = require("./TimelineSelection");
20
20
  const update_selected_easing_1 = require("./update-selected-easing");
21
+ const NAV_BUTTON_SIZE = 14;
22
+ const INSPECTOR_NAV_BUTTON_WIDTH = NAV_BUTTON_SIZE / 2;
23
+ const INSPECTOR_PREVIOUS_BUTTON_EXTRA_GAP = 1;
21
24
  const controlsContainerStyle = {
22
25
  alignItems: 'center',
23
26
  display: 'flex',
@@ -25,6 +28,12 @@ const controlsContainerStyle = {
25
28
  gap: 1,
26
29
  marginRight: 4,
27
30
  };
31
+ const inspectorControlsContainerStyle = {
32
+ ...controlsContainerStyle,
33
+ paddingLeft: NAV_BUTTON_SIZE -
34
+ INSPECTOR_NAV_BUTTON_WIDTH -
35
+ INSPECTOR_PREVIOUS_BUTTON_EXTRA_GAP,
36
+ };
28
37
  const navButtonStyle = {
29
38
  alignItems: 'center',
30
39
  background: 'none',
@@ -33,13 +42,20 @@ const navButtonStyle = {
33
42
  cursor: 'pointer',
34
43
  display: 'flex',
35
44
  flexShrink: 0,
36
- height: 14,
45
+ height: NAV_BUTTON_SIZE,
37
46
  justifyContent: 'center',
38
47
  lineHeight: 1,
39
48
  outline: 'none',
40
49
  padding: 0,
41
50
  userSelect: 'none',
42
- width: 14,
51
+ width: NAV_BUTTON_SIZE,
52
+ };
53
+ const inspectorNavButtonStyle = {
54
+ width: INSPECTOR_NAV_BUTTON_WIDTH,
55
+ };
56
+ const inspectorPreviousNavButtonStyle = {
57
+ ...inspectorNavButtonStyle,
58
+ marginRight: INSPECTOR_PREVIOUS_BUTTON_EXTRA_GAP,
43
59
  };
44
60
  const isKeyframedStatus = (status) => {
45
61
  return status.status === 'keyframed';
@@ -48,7 +64,7 @@ const diamondButtonStyle = {
48
64
  ...navButtonStyle,
49
65
  background: 'none',
50
66
  };
51
- const svgStyle = { display: 'block' };
67
+ const svgStyle = { display: 'block', flexShrink: 0 };
52
68
  const isKeyframeControlSelection = (selection) => {
53
69
  return (selection.type === 'sequence-prop' ||
54
70
  selection.type === 'sequence-effect-prop');
@@ -454,23 +470,27 @@ const TimelineKeyframeControls = ({ fieldKey, propStatus, nodePath, fileName, ke
454
470
  const nextDisabled = nextDisplayFrame === null;
455
471
  const previousStyle = (0, react_1.useMemo)(() => ({
456
472
  ...navButtonStyle,
473
+ ...(mode === 'inspector' ? inspectorPreviousNavButtonStyle : null),
457
474
  cursor: previousDisabled ? 'default' : 'pointer',
458
475
  opacity: previousDisabled ? 0.35 : 1,
459
476
  visibility: showNavigationButtons ? 'visible' : 'hidden',
460
- }), [previousDisabled, showNavigationButtons]);
477
+ }), [mode, previousDisabled, showNavigationButtons]);
461
478
  const nextStyle = (0, react_1.useMemo)(() => ({
462
479
  ...navButtonStyle,
480
+ ...(mode === 'inspector' ? inspectorNavButtonStyle : null),
463
481
  cursor: nextDisabled ? 'default' : 'pointer',
464
482
  opacity: nextDisabled ? 0.35 : 1,
465
483
  visibility: showNavigationButtons ? 'visible' : 'hidden',
466
- }), [nextDisabled, showNavigationButtons]);
484
+ }), [mode, nextDisabled, showNavigationButtons]);
467
485
  const diamondStyle = (0, react_1.useMemo)(() => ({
468
486
  ...diamondButtonStyle,
469
487
  cursor: canToggleKeyframe && clientId ? 'pointer' : 'default',
470
488
  opacity: canToggleKeyframe && clientId ? 1 : 0.35,
471
489
  }), [canToggleKeyframe, clientId]);
472
490
  const diamondColor = hasKeyframeAtCurrentFrame ? colors_1.BLUE : colors_1.LIGHT_TEXT;
473
- return (jsx_runtime_1.jsxs("div", { style: controlsContainerStyle, children: [
491
+ return (jsx_runtime_1.jsxs("div", { style: mode === 'inspector'
492
+ ? inspectorControlsContainerStyle
493
+ : controlsContainerStyle, children: [
474
494
  jsx_runtime_1.jsx("button", { type: "button", style: previousStyle, disabled: previousDisabled, onPointerDown: previousDisabled ? undefined : onPrevious, "aria-label": "Go to previous keyframe", title: "Previous keyframe", children: jsx_runtime_1.jsx("svg", { width: "14", height: "14", viewBox: "0 0 10 10", style: svgStyle, children: jsx_runtime_1.jsx("path", { d: "M7 1.5L3 5L7 8.5Z", fill: colors_1.LIGHT_GRAY }) }) }), jsx_runtime_1.jsx("button", { type: "button", style: diamondStyle, disabled: !canToggleKeyframe || !clientId, onPointerDown: canToggleKeyframe && clientId ? onToggleKeyframe : undefined, "aria-label": hasKeyframeAtCurrentFrame ? 'Remove keyframe' : 'Add keyframe', title: hasKeyframeAtCurrentFrame ? 'Remove keyframe' : 'Add keyframe', children: jsx_runtime_1.jsx(TimelineKeyframeDiamondIcon_1.TimelineKeyframeDiamondIcon, { color: diamondColor, size: 12 }) }), jsx_runtime_1.jsx("button", { type: "button", style: nextStyle, disabled: nextDisabled, onPointerDown: nextDisabled ? undefined : onNext, "aria-label": "Go to next keyframe", title: "Next keyframe", children: jsx_runtime_1.jsx("svg", { width: "14", height: "14", viewBox: "0 0 10 10", style: svgStyle, children: jsx_runtime_1.jsx("path", { d: "M3 1.5L7 5L3 8.5Z", fill: colors_1.LIGHT_GRAY }) }) })
475
495
  ] }));
476
496
  };
@@ -2,18 +2,23 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineList = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
5
6
  const colors_1 = require("../../helpers/colors");
7
+ const nest_timeline_tracks_1 = require("./nest-timeline-tracks");
6
8
  const TimelineSequenceItem_1 = require("./TimelineSequenceItem");
7
9
  const TimelineTimeIndicators_1 = require("./TimelineTimeIndicators");
8
10
  const container = {
9
11
  flex: 1,
10
12
  background: colors_1.BACKGROUND,
11
13
  };
14
+ const TimelineListTrack = ({ nestedTrack }) => {
15
+ var _a;
16
+ const { track, children, siblingIndex } = nestedTrack;
17
+ return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { siblingIndex: siblingIndex, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset, children: children.map((child) => (jsx_runtime_1.jsx(TimelineListTrack, { nestedTrack: child }, child.track.sequence.id))) }) }));
18
+ };
12
19
  const TimelineList = ({ timeline }) => {
20
+ const nestedTimeline = (0, react_1.useMemo)(() => (0, nest_timeline_tracks_1.nestTimelineTracks)(timeline), [timeline]);
13
21
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
14
- jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), timeline.map((track, trackIndex) => {
15
- var _a;
16
- return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(TimelineSequenceItem_1.TimelineSequenceItem, { trackIndex: trackIndex, connectedCompositions: (_a = track.connectedCompositions) !== null && _a !== void 0 ? _a : [], nestedDepth: track.depth, sequence: track.sequence, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, sequenceFrameOffset: track.sequenceFrameOffset }, track.sequence.id) }, track.sequence.id));
17
- })] }));
22
+ jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePadding, {}), nestedTimeline.map((nestedTrack) => (jsx_runtime_1.jsx(TimelineListTrack, { nestedTrack: nestedTrack }, nestedTrack.track.sequence.id)))] }));
18
23
  };
19
24
  exports.TimelineList = TimelineList;
@@ -26,7 +26,7 @@ const keyframeControlsColumnBaseStyle = {
26
26
  };
27
27
  const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, style, selected, selectable, selectionItem, onSelect, showSelectedBackground, containsSelection, outerHeight, onDragLeave, onDragOver, onDrop, onDoubleClick, }) => {
28
28
  const ref = (0, react_1.useRef)(null);
29
- const { basePadding, keyframeControlsPadding } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
29
+ const { basePadding, keyframeControlsPadding, rowBorderRadius, rowHorizontalMargin, } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
30
30
  const indentWidth = (0, timeline_row_layout_1.getTimelineRowIndentWidth)(depth);
31
31
  (0, TimelineSelection_1.useTimelineFocusableItem)(selectionItem, ref);
32
32
  const keyframeControlsColumnStyle = (0, react_1.useMemo)(() => ({
@@ -64,7 +64,15 @@ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, styl
64
64
  ...rowBase,
65
65
  ...style,
66
66
  backgroundColor: outerHeight === null ? highlightBackground : undefined,
67
- }), [style, outerHeight, highlightBackground]);
67
+ borderRadius: rowBorderRadius,
68
+ margin: `0 ${rowHorizontalMargin}px`,
69
+ }), [
70
+ style,
71
+ outerHeight,
72
+ highlightBackground,
73
+ rowBorderRadius,
74
+ rowHorizontalMargin,
75
+ ]);
68
76
  const outerStyle = (0, react_1.useMemo)(() => {
69
77
  if (outerHeight === null) {
70
78
  return undefined;
@@ -1,6 +1,9 @@
1
1
  type TimelineRowLayout = {
2
2
  readonly basePadding: number;
3
+ readonly highlightSelectedLabel: boolean;
3
4
  readonly keyframeControlsPadding: number;
5
+ readonly rowBorderRadius: number;
6
+ readonly rowHorizontalMargin: number;
4
7
  };
5
8
  export declare const INSPECTOR_TIMELINE_ROW_LAYOUT: TimelineRowLayout;
6
9
  export declare const TimelineRowLayoutContext: import("react").Context<TimelineRowLayout>;