@remotion/studio 4.0.524 → 4.0.525

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/components/ActionTooltip.d.ts +2 -0
  2. package/dist/components/ActionTooltip.js +14 -4
  3. package/dist/components/AppLaunchButton.js +2 -0
  4. package/dist/components/AssetSelectorModal.d.ts +6 -0
  5. package/dist/components/AssetSelectorModal.js +174 -0
  6. package/dist/components/Canvas.js +15 -1
  7. package/dist/components/CheckboardToggle.js +2 -1
  8. package/dist/components/ColorPicker/AlphaSlider.js +1 -1
  9. package/dist/components/ColorPicker/HueSlider.js +1 -1
  10. package/dist/components/ColorPicker/SaturationValueArea.js +1 -1
  11. package/dist/components/CompositionSelector.js +1 -0
  12. package/dist/components/CompositionSelectorItem.js +1 -0
  13. package/dist/components/EditorGuides/Guide.js +1 -1
  14. package/dist/components/ElementInstallConfirmation.js +31 -23
  15. package/dist/components/FullscreenToggle.js +1 -1
  16. package/dist/components/GlobalKeybindings.js +14 -0
  17. package/dist/components/InspectorLocationCopy.js +1 -1
  18. package/dist/components/InspectorOpenInEditor.d.ts +1 -0
  19. package/dist/components/InspectorOpenInEditor.js +18 -15
  20. package/dist/components/InspectorPanel/CompositionInspectorHeader.js +6 -7
  21. package/dist/components/InspectorPanel/CompositionMetadata.js +1 -0
  22. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -0
  23. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +4 -12
  24. package/dist/components/InspectorSequenceSection.js +18 -9
  25. package/dist/components/LoopToggle.js +2 -1
  26. package/dist/components/Menu/MenuItem.js +1 -2
  27. package/dist/components/MenuBuildIndicator.js +1 -1
  28. package/dist/components/Modals.js +2 -1
  29. package/dist/components/MuteToggle.js +2 -1
  30. package/dist/components/NewComposition/CodemodFooter.js +1 -0
  31. package/dist/components/NewComposition/DeleteComposition.js +42 -6
  32. package/dist/components/NewComposition/DeleteFolder.js +1 -0
  33. package/dist/components/NewComposition/DuplicateComposition.js +5 -0
  34. package/dist/components/NewComposition/InputDragger.js +2 -2
  35. package/dist/components/NewComposition/NewFolder.js +29 -2
  36. package/dist/components/NewComposition/RenameFolder.js +1 -0
  37. package/dist/components/NewComposition/duplicate-composition-api.d.ts +3 -2
  38. package/dist/components/NewComposition/duplicate-composition-api.js +9 -2
  39. package/dist/components/Notifications/NotificationCenter.d.ts +1 -0
  40. package/dist/components/Notifications/NotificationCenter.js +22 -1
  41. package/dist/components/OutlineToggle.js +2 -1
  42. package/dist/components/PlayPause.js +1 -1
  43. package/dist/components/Preview.js +0 -3
  44. package/dist/components/PreviewToolbar.js +3 -6
  45. package/dist/components/PreviewToolbarOverflowButton.js +2 -1
  46. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +1 -1
  47. package/dist/components/RenderButton.js +40 -4
  48. package/dist/components/RenderModal/WebRenderModalBasic.js +1 -1
  49. package/dist/components/RenderModal/render-modals.js +3 -0
  50. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +1 -1
  51. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +1 -1
  52. package/dist/components/RenderQueue/actions.d.ts +2 -1
  53. package/dist/components/RenderQueue/actions.js +2 -1
  54. package/dist/components/RulersAndGuidesToggle.js +2 -1
  55. package/dist/components/SegmentedButton.d.ts +1 -0
  56. package/dist/components/SegmentedButton.js +9 -3
  57. package/dist/components/SelectedOutlineElement.js +16 -6
  58. package/dist/components/SelectedOutlinePolygon.js +4 -2
  59. package/dist/components/SettingsContext.d.ts +8 -0
  60. package/dist/components/SettingsContext.js +57 -2
  61. package/dist/components/SettingsModal.js +4 -1
  62. package/dist/components/SettingsModalFooter.js +1 -1
  63. package/dist/components/SidebarCollapserControls.js +1 -1
  64. package/dist/components/SkillsSettings.js +35 -4
  65. package/dist/components/SnappingToggle.js +2 -1
  66. package/dist/components/Splitter/SplitterHandle.js +1 -2
  67. package/dist/components/Tabs/vertical.d.ts +1 -1
  68. package/dist/components/Tabs/vertical.js +16 -2
  69. package/dist/components/Timeline/EasingEditorModal.js +2 -2
  70. package/dist/components/Timeline/TimelineAssetField.js +148 -9
  71. package/dist/components/Timeline/TimelineDragHandler.js +1 -2
  72. package/dist/components/Timeline/TimelineEffectItem.d.ts +1 -0
  73. package/dist/components/Timeline/TimelineEffectItem.js +2 -2
  74. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  75. package/dist/components/Timeline/TimelineEffectPropItem.js +2 -2
  76. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  77. package/dist/components/Timeline/TimelineInOutDragHandler.js +1 -2
  78. package/dist/components/Timeline/TimelineSchemaField.js +8 -1
  79. package/dist/components/Timeline/TimelineSelection.d.ts +3 -1
  80. package/dist/components/Timeline/TimelineSelection.js +32 -5
  81. package/dist/components/Timeline/TimelineSequence.js +6 -6
  82. package/dist/components/Timeline/TimelineSequenceItem.js +12 -10
  83. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +3 -12
  84. package/dist/components/Timeline/TimelineTranslateField.js +25 -12
  85. package/dist/components/Timeline/TimelineZoomControls.js +1 -1
  86. package/dist/components/Timeline/get-sequence-context-menu-items.js +22 -6
  87. package/dist/components/Timeline/timeline-field-display-utils.js +4 -2
  88. package/dist/components/Timeline/timeline-translate-utils.d.ts +17 -0
  89. package/dist/components/Timeline/timeline-translate-utils.js +53 -12
  90. package/dist/components/Timeline/use-open-sequence-in-apps.d.ts +2 -0
  91. package/dist/components/Timeline/use-open-sequence-in-apps.js +17 -0
  92. package/dist/components/Timeline/use-timeline-asset-drop.js +17 -3
  93. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  94. package/dist/components/TimelineCombobox.js +1 -0
  95. package/dist/components/UndoRedoButtons.js +11 -0
  96. package/dist/components/composition-menu-items.js +56 -2
  97. package/dist/components/folder-menu-items.js +44 -0
  98. package/dist/components/get-open-in-menu-items.js +1 -1
  99. package/dist/components/import-assets.d.ts +24 -1
  100. package/dist/components/import-assets.js +3 -1
  101. package/dist/components/keyboard-shortcuts.d.ts +4 -4
  102. package/dist/components/keyboard-shortcuts.js +5 -0
  103. package/dist/esm/{LazyModels-hc33szyn.mjs → LazyModels-gfmpcy4h.mjs} +3 -3
  104. package/dist/esm/{LazyModels-sg40rjw6.mjs → LazyModels-m1rf06wh.mjs} +3 -3
  105. package/dist/esm/{TranscriptionModal-3ctnxpt6.mjs → TranscriptionModal-8pvrehg4.mjs} +6 -6
  106. package/dist/esm/{VideoMattingModal-b0r7e60n.mjs → VideoMattingModal-fefbzgka.mjs} +6 -6
  107. package/dist/esm/{index-yfrysr5f.mjs → index-0x13f28h.mjs} +17 -3
  108. package/dist/esm/{index-q2epbw93.mjs → index-1089795y.mjs} +2 -2
  109. package/dist/esm/{index-9qtvmwtx.mjs → index-41kqns5c.mjs} +4 -2
  110. package/dist/esm/{index-c37kme2v.mjs → index-ggqpre9v.mjs} +2202 -1719
  111. package/dist/esm/{index-wbmp5srk.mjs → index-hbezgbbq.mjs} +1 -1
  112. package/dist/esm/{index-2j3d1g81.mjs → index-jrw61pkj.mjs} +1 -1
  113. package/dist/esm/{index-1b9skrrd.mjs → index-mww32xc8.mjs} +3 -3
  114. package/dist/esm/{index-er3mh6em.mjs → index-s848rffx.mjs} +7123 -6588
  115. package/dist/esm/{index-q5xv20xx.mjs → index-tzxb8808.mjs} +1 -1
  116. package/dist/esm/{index-e3zwf3e7.mjs → index-vsxrxfpj.mjs} +1 -1
  117. package/dist/esm/index.mjs +2 -2
  118. package/dist/esm/internals.mjs +7 -7
  119. package/dist/esm/previewEntry.mjs +7 -7
  120. package/dist/helpers/get-git-menu-item.d.ts +4 -0
  121. package/dist/helpers/get-git-menu-item.js +8 -1
  122. package/dist/helpers/get-sequence-double-click-action.d.ts +3 -3
  123. package/dist/helpers/get-sequence-double-click-action.js +2 -2
  124. package/dist/helpers/pointer-session.d.ts +1 -0
  125. package/dist/helpers/pointer-session.js +10 -1
  126. package/dist/helpers/studio-runtime-config.d.ts +1 -1
  127. package/dist/helpers/use-create-composition.js +5 -0
  128. package/dist/helpers/use-keybinding.d.ts +1 -1
  129. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -2
  130. package/dist/helpers/use-media-metadata.js +5 -1
  131. package/dist/helpers/use-menu-structure.js +5 -1
  132. package/dist/helpers/use-rename-composition.js +6 -1
  133. package/dist/state/modals.d.ts +13 -1
  134. package/dist/state/z-index.js +1 -3
  135. package/package.json +19 -19
@@ -5,5 +5,7 @@ export declare const ActionTooltip: React.FC<{
5
5
  /** Hover delay in milliseconds. Pass null to show immediately. */
6
6
  readonly delay: number | null;
7
7
  readonly dismissOnClick: boolean;
8
+ readonly side?: 'top' | 'right';
9
+ readonly triggerStyle?: React.CSSProperties;
8
10
  readonly children: React.ReactNode;
9
11
  }>;
@@ -8,7 +8,7 @@ const colors_1 = require("../helpers/colors");
8
8
  const z_index_1 = require("../state/z-index");
9
9
  const portals_1 = require("./Menu/portals");
10
10
  const styles_1 = require("./Menu/styles");
11
- const triggerStyle = { display: 'inline-flex' };
11
+ const defaultTriggerStyle = { display: 'inline-flex' };
12
12
  const tooltipStyle = {
13
13
  position: 'fixed',
14
14
  display: 'flex',
@@ -44,7 +44,7 @@ const shortcutStyle = {
44
44
  let visibleTooltipCount = 0;
45
45
  let lastTooltipHiddenAt = null;
46
46
  const TOOLTIP_SKIP_DELAY_WINDOW = 300;
47
- const ActionTooltip = ({ label, shortcut, delay, dismissOnClick, children }) => {
47
+ const ActionTooltip = ({ label, shortcut, delay, dismissOnClick, side = 'top', triggerStyle, children, }) => {
48
48
  var _a, _b;
49
49
  const triggerRef = (0, react_1.useRef)(null);
50
50
  const tooltipRef = (0, react_1.useRef)(null);
@@ -119,14 +119,24 @@ const ActionTooltip = ({ label, shortcut, delay, dismissOnClick, children }) =>
119
119
  }
120
120
  const trigger = triggerRef.current.getBoundingClientRect();
121
121
  const tooltip = tooltipRef.current.getBoundingClientRect();
122
+ if (side === 'right') {
123
+ const right = trigger.right + 4;
124
+ setPosition({
125
+ left: right + tooltip.width <= window.innerWidth - 8
126
+ ? right
127
+ : Math.max(8, trigger.left - tooltip.width - 4),
128
+ top: Math.max(8, Math.min(trigger.top + (trigger.height - tooltip.height) / 2, window.innerHeight - tooltip.height - 8)),
129
+ });
130
+ return;
131
+ }
122
132
  const above = trigger.top - tooltip.height - 4;
123
133
  setPosition({
124
134
  left: Math.max(8, Math.min(trigger.left + (trigger.width - tooltip.width) / 2, window.innerWidth - tooltip.width - 8)),
125
135
  top: Math.max(8, Math.min(above >= 8 ? above : trigger.bottom + 4, window.innerHeight - tooltip.height - 8)),
126
136
  });
127
- }, [label, shortcut, visible]);
137
+ }, [label, shortcut, side, visible]);
128
138
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
129
- jsx_runtime_1.jsx("span", { ref: triggerRef, style: triggerStyle, onPointerEnter: onPointerEnter, onPointerLeave: hide, onPointerDownCapture: dismissOnClick ? hide : undefined, onClickCapture: dismissOnClick ? hide : undefined, onFocus: (event) => {
139
+ jsx_runtime_1.jsx("span", { ref: triggerRef, style: { ...defaultTriggerStyle, ...triggerStyle }, onPointerEnter: onPointerEnter, onPointerLeave: hide, onPointerDownCapture: dismissOnClick ? hide : undefined, onClickCapture: dismissOnClick ? hide : undefined, onFocus: (event) => {
130
140
  if (event.currentTarget.contains(event.target)) {
131
141
  show();
132
142
  }
@@ -51,6 +51,7 @@ const AppLaunchButton = ({ actionButtonId, ariaLabel, children, disabled, menuAr
51
51
  ? defaultMainSegmentStyle
52
52
  : compactMainSegmentStyle,
53
53
  title,
54
+ tooltipLabel: null,
54
55
  type: 'action',
55
56
  },
56
57
  ...(items.length > 0
@@ -67,6 +68,7 @@ const AppLaunchButton = ({ actionButtonId, ariaLabel, children, disabled, menuAr
67
68
  selectedId: null,
68
69
  style: dropdownSegmentStyle,
69
70
  title: menuAriaLabel,
71
+ tooltipLabel: null,
70
72
  type: 'menu',
71
73
  values: items,
72
74
  },
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { type AssetSelectionModalState } from '../state/modals';
3
+ export declare const AssetSelectorModal: React.FC<{
4
+ readonly state: AssetSelectionModalState;
5
+ readonly readOnlyStudio: boolean;
6
+ }>;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetSelectorModal = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const colors_1 = require("../helpers/colors");
7
+ const modals_1 = require("../state/modals");
8
+ const Button_1 = require("./Button");
9
+ const layout_1 = require("./layout");
10
+ const ModalButton_1 = require("./ModalButton");
11
+ const ModalContainer_1 = require("./ModalContainer");
12
+ const ModalFooter_1 = require("./ModalFooter");
13
+ const ModalHeader_1 = require("./ModalHeader");
14
+ const RemInput_1 = require("./NewComposition/RemInput");
15
+ const QuickSwitcherContent_1 = require("./QuickSwitcher/QuickSwitcherContent");
16
+ const SegmentedControl_1 = require("./SegmentedControl");
17
+ const panel = {
18
+ maxWidth: 'calc(100vw - 40px)',
19
+ overflow: 'hidden',
20
+ width: 400,
21
+ };
22
+ const sourceSelector = {
23
+ display: 'flex',
24
+ padding: '12px 16px 0',
25
+ };
26
+ const urlContent = {
27
+ boxSizing: 'border-box',
28
+ minHeight: 300,
29
+ padding: 16,
30
+ };
31
+ const compactUrlContent = {
32
+ boxSizing: 'border-box',
33
+ padding: 16,
34
+ };
35
+ const label = {
36
+ color: colors_1.LIGHT_TEXT,
37
+ display: 'block',
38
+ fontFamily: 'sans-serif',
39
+ fontSize: 12,
40
+ marginBottom: 8,
41
+ };
42
+ const previewRow = {
43
+ alignItems: 'center',
44
+ display: 'flex',
45
+ gap: 16,
46
+ minHeight: 112,
47
+ paddingTop: 16,
48
+ };
49
+ const previewImage = {
50
+ display: 'block',
51
+ height: 96,
52
+ objectFit: 'contain',
53
+ width: 96,
54
+ };
55
+ const previewStatus = {
56
+ color: colors_1.LIGHT_TEXT,
57
+ fontFamily: 'sans-serif',
58
+ fontSize: 12,
59
+ lineHeight: 1.5,
60
+ };
61
+ const footer = {
62
+ display: 'flex',
63
+ minWidth: 0,
64
+ width: '100%',
65
+ };
66
+ const isHttpUrl = (value) => {
67
+ try {
68
+ const { protocol } = new URL(value.startsWith('//') ? `https:${value}` : value);
69
+ return protocol === 'http:' || protocol === 'https:';
70
+ }
71
+ catch (_a) {
72
+ return false;
73
+ }
74
+ };
75
+ const AssetSelectorModal = ({ state, readOnlyStudio }) => {
76
+ var _a;
77
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.SetSelectedModalContext);
78
+ const [mode, setMode] = (0, react_1.useState)(() => state.initialUrl === null ? 'project' : 'url');
79
+ const [draft, setDraft] = (0, react_1.useState)((_a = state.initialUrl) !== null && _a !== void 0 ? _a : '');
80
+ const [previewState, setPreviewState] = (0, react_1.useState)(() => state.assetType === 'image' && state.initialUrl !== null
81
+ ? { type: 'loading' }
82
+ : { type: 'empty' });
83
+ const close = (0, react_1.useCallback)(() => {
84
+ setSelectedModal(null);
85
+ }, [setSelectedModal]);
86
+ (0, react_1.useEffect)(() => {
87
+ if (state.assetType !== 'image') {
88
+ setPreviewState({ type: 'empty' });
89
+ return;
90
+ }
91
+ const value = draft.trim();
92
+ if (value === '') {
93
+ setPreviewState({ type: 'empty' });
94
+ return;
95
+ }
96
+ if (!isHttpUrl(value)) {
97
+ setPreviewState({ type: 'invalid' });
98
+ return;
99
+ }
100
+ let cancelled = false;
101
+ const image = new Image();
102
+ setPreviewState({ type: 'loading' });
103
+ image.onload = () => {
104
+ if (!cancelled) {
105
+ setPreviewState({
106
+ type: 'loaded',
107
+ width: image.naturalWidth,
108
+ height: image.naturalHeight,
109
+ });
110
+ }
111
+ };
112
+ image.onerror = () => {
113
+ if (!cancelled) {
114
+ setPreviewState({ type: 'error' });
115
+ }
116
+ };
117
+ image.src = value.startsWith('//') ? `https:${value}` : value;
118
+ return () => {
119
+ cancelled = true;
120
+ image.onload = null;
121
+ image.onerror = null;
122
+ };
123
+ }, [draft, state.assetType]);
124
+ const items = (0, react_1.useMemo)(() => [
125
+ {
126
+ key: 'project',
127
+ label: 'Project assets',
128
+ onClick: () => setMode('project'),
129
+ selected: mode === 'project',
130
+ },
131
+ {
132
+ key: 'url',
133
+ label: 'URL',
134
+ onClick: () => setMode('url'),
135
+ selected: mode === 'url',
136
+ },
137
+ ], [mode]);
138
+ const trimmedDraft = draft.trim();
139
+ const canApply = isHttpUrl(trimmedDraft);
140
+ const invalidDraft = trimmedDraft !== '' && !canApply;
141
+ const apply = (0, react_1.useCallback)(() => {
142
+ if (!canApply) {
143
+ return;
144
+ }
145
+ state.onSelectedUrl(trimmedDraft);
146
+ close();
147
+ }, [canApply, close, state, trimmedDraft]);
148
+ const onSubmit = (0, react_1.useCallback)((event) => {
149
+ event.preventDefault();
150
+ apply();
151
+ }, [apply]);
152
+ const assetTypeLabel = state.assetType.charAt(0).toUpperCase() + state.assetType.slice(1);
153
+ return (jsx_runtime_1.jsxs(ModalContainer_1.ModalContainer, { onEscape: close, onOutsideClick: close, panelStyle: panel, children: [
154
+ jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Replace ${state.assetType}`, onClose: close }), jsx_runtime_1.jsx("div", { style: sourceSelector, children: jsx_runtime_1.jsx(SegmentedControl_1.SegmentedControl, { items: items, needsWrapping: false, size: "compact" }) }), mode === 'project' ? (jsx_runtime_1.jsx(QuickSwitcherContent_1.QuickSwitcherContent, { assetSelection: state.assetSelection, compositionSelection: null, initialMode: "assets", invocationTimestamp: state.invocationTimestamp, readOnlyStudio: readOnlyStudio })) : (jsx_runtime_1.jsxs("form", { onSubmit: onSubmit, children: [
155
+ jsx_runtime_1.jsxs("div", { style: state.assetType === 'image' ? urlContent : compactUrlContent, children: [
156
+ jsx_runtime_1.jsxs("label", { htmlFor: "remotion-asset-url", style: label, children: [assetTypeLabel, " URL"] }), jsx_runtime_1.jsx(RemInput_1.RemotionInput, { id: "remotion-asset-url", autoFocus: true, onChange: (event) => setDraft(event.target.value), placeholder: `https://example.com/${state.assetType}`, rightAlign: false, status: invalidDraft ? 'error' : 'ok', type: "url", value: draft }), state.assetType === 'image' ? (jsx_runtime_1.jsxs("div", { style: previewRow, role: "status", children: [previewState.type === 'loaded' ? (jsx_runtime_1.jsx("img", { alt: "Image URL preview", src: trimmedDraft.startsWith('//')
157
+ ? `https:${trimmedDraft}`
158
+ : trimmedDraft, style: previewImage })) : null, jsx_runtime_1.jsx("div", { style: previewState.type === 'error'
159
+ ? { ...previewStatus, color: colors_1.FAIL_COLOR }
160
+ : previewStatus, children: previewState.type === 'empty'
161
+ ? 'Enter an image URL.'
162
+ : previewState.type === 'invalid'
163
+ ? 'Enter an HTTP(S) URL.'
164
+ : previewState.type === 'loading'
165
+ ? 'Loading preview…'
166
+ : previewState.type === 'error'
167
+ ? 'Preview unavailable. You can still replace the source.'
168
+ : `${previewState.width} × ${previewState.height}` })
169
+ ] })) : null] }), jsx_runtime_1.jsx(ModalFooter_1.ModalFooterContainer, { style: footer, children: jsx_runtime_1.jsxs(layout_1.Row, { align: "center", flex: 1, justify: "flex-end", children: [
170
+ jsx_runtime_1.jsx(Button_1.Button, { onClick: close, children: "Cancel" }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsxs(ModalButton_1.ModalButton, { disabled: !canApply, onClick: apply, children: ["Replace ", state.assetType] })
171
+ ] }) })
172
+ ] }))] }));
173
+ };
174
+ exports.AssetSelectorModal = AssetSelectorModal;
@@ -155,6 +155,7 @@ const Canvas = ({ canvasContent, size }) => {
155
155
  const [pendingElementInstallRequests, setPendingElementInstallRequests] = (0, react_1.useState)([]);
156
156
  const [activeElementInstallRequest, setActiveElementInstallRequest] = (0, react_1.useState)(null);
157
157
  const lastFocusedAtRef = (0, react_1.useRef)(typeof document === 'undefined' || document.hasFocus() ? Date.now() : null);
158
+ const unsupportedDropNotifiedRef = (0, react_1.useRef)(false);
158
159
  const [assetResolution, setAssetResolution] = (0, react_1.useState)(null);
159
160
  const metadataRequestRef = (0, react_1.useRef)(0);
160
161
  const currentCompositionId = canvasContent.type === 'composition' ? canvasContent.compositionId : null;
@@ -843,10 +844,17 @@ const Canvas = ({ canvasContent, size }) => {
843
844
  var _a;
844
845
  var _b;
845
846
  if (!(0, drop_handler_data_1.isSupportedDropEvent)(event) || !isDragEventInsideCanvas(event)) {
847
+ unsupportedDropNotifiedRef.current = false;
846
848
  setCompositionDropPreview(null);
847
849
  return;
848
850
  }
849
851
  const mayBeCanvasCapture = (0, drop_handler_data_1.isFileDragEvent)(event) && !window.remotion_isReadOnlyStudio;
852
+ const shouldNotifyAboutUnsupportedDrop = cannotAddSequence && !mayBeCanvasCapture;
853
+ if (shouldNotifyAboutUnsupportedDrop &&
854
+ !unsupportedDropNotifiedRef.current) {
855
+ (0, NotificationCenter_1.showCannotAddSequenceDropNotification)();
856
+ }
857
+ unsupportedDropNotifiedRef.current = shouldNotifyAboutUnsupportedDrop;
850
858
  if (!canDropAssets && !cannotAddSequence && !mayBeCanvasCapture) {
851
859
  setCompositionDropPreview(null);
852
860
  return;
@@ -939,14 +947,18 @@ const Canvas = ({ canvasContent, size }) => {
939
947
  return;
940
948
  }
941
949
  }
950
+ unsupportedDropNotifiedRef.current = false;
942
951
  setCompositionDropPreview(null);
943
952
  }, []);
944
953
  const onDragEnd = (0, react_1.useCallback)(() => {
954
+ unsupportedDropNotifiedRef.current = false;
945
955
  setCompositionDropPreview(null);
946
956
  }, []);
947
957
  const onDrop = (0, react_1.useCallback)(async (event) => {
948
958
  var _a, _b;
949
959
  var _c, _d;
960
+ const unsupportedDropWasNotified = unsupportedDropNotifiedRef.current;
961
+ unsupportedDropNotifiedRef.current = false;
950
962
  setCompositionDropPreview(null);
951
963
  if (!(0, drop_handler_data_1.isSupportedDropEvent)(event) || !isDragEventInsideCanvas(event)) {
952
964
  return;
@@ -975,7 +987,9 @@ const Canvas = ({ canvasContent, size }) => {
975
987
  if (cannotAddSequence) {
976
988
  event.preventDefault();
977
989
  event.stopPropagation();
978
- (0, NotificationCenter_1.showNotification)('Cannot insert items into this composition component', 3000);
990
+ if (!unsupportedDropWasNotified) {
991
+ (0, NotificationCenter_1.showCannotAddSequenceDropNotification)();
992
+ }
979
993
  return;
980
994
  }
981
995
  if (!canDropAssets ||
@@ -9,6 +9,7 @@ const use_keyboard_shortcut_label_1 = require("../helpers/use-keyboard-shortcut-
9
9
  const checkerboard_1 = require("../state/checkerboard");
10
10
  const ActionTooltip_1 = require("./ActionTooltip");
11
11
  const ControlButton_1 = require("./ControlButton");
12
+ const buttonStyle = { width: 26 };
12
13
  const CheckboardToggle = () => {
13
14
  const { checkerboard, setCheckerboard } = (0, react_1.useContext)(checkerboard_1.CheckerboardContext);
14
15
  const onClick = (0, react_1.useCallback)(() => {
@@ -20,7 +21,7 @@ const CheckboardToggle = () => {
20
21
  const ariaKeyShortcuts = (0, use_keyboard_shortcut_label_1.useKeyboardShortcutAriaKeyShortcuts)('toggleCheckerboard');
21
22
  const accessibilityLabel = 'Show transparency as checkerboard';
22
23
  const shortcutsDisabled = (0, use_keybinding_1.areKeyboardShortcutsDisabled)();
23
- return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: accessibilityLabel, shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-pressed": checkerboard, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaKeyShortcuts || undefined, onClick: onClick, children: (color) => (jsx_runtime_1.jsxs("svg", { "aria-hidden": "true", focusable: "false", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: { width: 18, height: 18 }, fill: "none", children: [
24
+ return (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Checkerboard", shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: false, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: "", "aria-label": accessibilityLabel, "aria-pressed": checkerboard, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaKeyShortcuts || undefined, onClick: onClick, style: buttonStyle, children: (color) => (jsx_runtime_1.jsxs("svg", { "aria-hidden": "true", focusable: "false", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", style: { width: 18, height: 18 }, fill: "none", children: [
24
25
  jsx_runtime_1.jsx("path", { fill: checkerboard ? colors_1.BLUE : color, d: "M256 48h184c13.3 0 24 10.7 24 24v184H256V48zM48 256h208v208H72c-13.3 0-24-10.7-24-24V256z" }), jsx_runtime_1.jsx("rect", { x: "48", y: "48", width: "416", height: "416", rx: "24", stroke: checkerboard ? colors_1.BLUE : color, strokeWidth: "32" }), jsx_runtime_1.jsx("path", { d: "M256 48v416M48 256h416", stroke: checkerboard ? colors_1.BLUE : color, strokeWidth: "32" })
25
26
  ] })) }) }));
26
27
  };
@@ -67,7 +67,7 @@ const AlphaSlider = ({ hue, saturation, value, alpha, onChange, onChangeComplete
67
67
  updateFromEvent(ev.clientX, false);
68
68
  },
69
69
  onEnd: (reason, ev) => {
70
- const shouldUseEndEvent = reason === 'pointerup' || reason === 'buttons-released';
70
+ const shouldUseEndEvent = (0, pointer_session_1.isPointerSessionRelease)(reason, ev);
71
71
  updateFromEvent(shouldUseEndEvent && ev ? ev.clientX : lastClientX, true);
72
72
  },
73
73
  });
@@ -49,7 +49,7 @@ const HueSlider = ({ hue, onChange, onChangeComplete }) => {
49
49
  updateFromEvent(ev.clientX, false);
50
50
  },
51
51
  onEnd: (reason, ev) => {
52
- const shouldUseEndEvent = reason === 'pointerup' || reason === 'buttons-released';
52
+ const shouldUseEndEvent = (0, pointer_session_1.isPointerSessionRelease)(reason, ev);
53
53
  updateFromEvent(shouldUseEndEvent && ev ? ev.clientX : lastClientX, true);
54
54
  },
55
55
  });
@@ -63,7 +63,7 @@ const SaturationValueArea = ({ hue, saturation, value, onChange, onChangeComplet
63
63
  updateFromEvent(ev.clientX, ev.clientY, false);
64
64
  },
65
65
  onEnd: (reason, ev) => {
66
- const shouldUseEndEvent = reason === 'pointerup' || reason === 'buttons-released';
66
+ const shouldUseEndEvent = (0, pointer_session_1.isPointerSessionRelease)(reason, ev);
67
67
  updateFromEvent(shouldUseEndEvent && ev ? ev.clientX : lastPosition.clientX, shouldUseEndEvent && ev ? ev.clientY : lastPosition.clientY, true);
68
68
  },
69
69
  });
@@ -238,6 +238,7 @@ const CompositionSelector = () => {
238
238
  dryRun: false,
239
239
  signal: controller.signal,
240
240
  symbolicatedStack: (0, composition_selector_drag_data_1.compositionSelectorDragDataToSymbolicatedStack)(dragData),
241
+ undoRedoNavigation: null,
241
242
  });
242
243
  if (result.success) {
243
244
  notification.dismiss();
@@ -408,6 +408,7 @@ const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, se
408
408
  dryRun: false,
409
409
  signal: new AbortController().signal,
410
410
  symbolicatedStack: (0, composition_selector_drag_data_1.compositionSelectorDragDataToSymbolicatedStack)(dragData),
411
+ undoRedoNavigation: null,
411
412
  });
412
413
  if (result.success) {
413
414
  notification.dismiss();
@@ -128,7 +128,7 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
128
128
  pointerDownPositionRef.current = null;
129
129
  const shouldDeleteGuide = shouldDeleteGuideRef.current;
130
130
  finishGuideInteraction();
131
- if (shouldDeleteGuide || reason !== 'pointerup' || !endEvent) {
131
+ if (shouldDeleteGuide || !(0, pointer_session_1.isPointerSessionRelease)(reason, endEvent)) {
132
132
  return;
133
133
  }
134
134
  if ((0, editor_guide_selection_1.isGuidePointerUpAClick)({
@@ -10,12 +10,14 @@ const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint")
10
10
  const colors_1 = require("../helpers/colors");
11
11
  const hoverable_1 = require("../helpers/hoverable");
12
12
  const resolved_stack_to_symbolicated_1 = require("../helpers/resolved-stack-to-symbolicated");
13
+ const url_state_1 = require("../helpers/url-state");
13
14
  const use_create_composition_1 = require("../helpers/use-create-composition");
14
15
  const validate_new_comp_data_1 = require("../helpers/validate-new-comp-data");
15
16
  const z_index_1 = require("../state/z-index");
16
17
  const Button_1 = require("./Button");
17
18
  const element_install_api_1 = require("./element-install-api");
18
19
  const import_assets_1 = require("./import-assets");
20
+ const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
19
21
  const layout_1 = require("./layout");
20
22
  const LazySyntaxHighlightedSource_1 = require("./LazySyntaxHighlightedSource");
21
23
  const is_menu_item_1 = require("./Menu/is-menu-item");
@@ -27,7 +29,6 @@ const ModalHeader_1 = require("./ModalHeader");
27
29
  const NewComposition_1 = require("./NewComposition/NewComposition");
28
30
  const RemInput_1 = require("./NewComposition/RemInput");
29
31
  const ValidationMessage_1 = require("./NewComposition/ValidationMessage");
30
- const NotificationCenter_1 = require("./Notifications/NotificationCenter");
31
32
  const RadioButton_1 = require("./RadioButton");
32
33
  const SegmentedControl_1 = require("./SegmentedControl");
33
34
  const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
@@ -254,6 +255,7 @@ const ElementInstallConfirmation = ({ state }) => {
254
255
  const sourcePreview = (0, react_1.useMemo)(() => makeSourceControlsVisible(request.element.sourceCode), [request.element.sourceCode]);
255
256
  const config = remotion_1.Internals.useUnsafeVideoConfig();
256
257
  const { canvasContent, compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
258
+ const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
257
259
  const currentCompositionMetadata = config === null ||
258
260
  (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) !== 'composition' ||
259
261
  canvasContent.compositionId !== request.compositionId
@@ -369,7 +371,7 @@ const ElementInstallConfirmation = ({ state }) => {
369
371
  canceled = true;
370
372
  };
371
373
  }, [folderCompositionFile, newPlan, request.element, selectedFolderStack]);
372
- const { compositionId: newCompositionId, createComposition, heightValidationMessage, nameValidationMessage, valid: newCompositionValuesAreValid, widthValidationMessage, } = (0, use_create_composition_1.useCreateComposition)({
374
+ const { codemod: newCompositionCodemod, compositionId: newCompositionId, heightValidationMessage, nameValidationMessage, valid: newCompositionValuesAreValid, widthValidationMessage, } = (0, use_create_composition_1.useCreateComposition)({
373
375
  canvasCapture: null,
374
376
  compositions,
375
377
  durationInFrames: newCompositionValues.durationInFrames,
@@ -426,9 +428,6 @@ const ElementInstallConfirmation = ({ state }) => {
426
428
  const activePlan = overwriteExisting
427
429
  ? existingDestination.plan
428
430
  : ((_f = preparedInstallation === null || preparedInstallation === void 0 ? void 0 : preparedInstallation.plan) !== null && _f !== void 0 ? _f : null);
429
- const [createdComposition, setCreatedComposition] = (0, react_1.useState)(null);
430
- const creationKey = JSON.stringify(newCompositionValues);
431
- const compositionAlreadyCreated = createdComposition === creationKey;
432
431
  (0, react_1.useEffect)(() => {
433
432
  if (selectedPlan === null) {
434
433
  return;
@@ -521,7 +520,7 @@ const ElementInstallConfirmation = ({ state }) => {
521
520
  : requestedName !== null))) &&
522
521
  (mode === 'current-composition'
523
522
  ? currentPlan !== null
524
- : (newCompositionValuesAreValid || compositionAlreadyCreated) &&
523
+ : newCompositionValuesAreValid &&
525
524
  folderTargetIsReady &&
526
525
  selectedNewCompositionPlan !== null);
527
526
  const submit = (0, react_1.useCallback)(async () => {
@@ -530,18 +529,6 @@ const ElementInstallConfirmation = ({ state }) => {
530
529
  return;
531
530
  }
532
531
  setSubmitting(true);
533
- if (mode === 'new-composition' && !compositionAlreadyCreated) {
534
- const created = await createComposition({
535
- signal: new AbortController().signal,
536
- symbolicatedStack: selectedFolderStack === null ? null : folderSymbolicatedStack,
537
- });
538
- if (!created.success) {
539
- (0, NotificationCenter_1.showNotification)(`Could not create composition: ${created.reason}`, 4000);
540
- setSubmitting(false);
541
- return;
542
- }
543
- setCreatedComposition(creationKey);
544
- }
545
532
  const installed = await (0, import_assets_1.insertElement)({
546
533
  installationName: overwriteExisting
547
534
  ? ((_a = existingDestination === null || existingDestination === void 0 ? void 0 : existingDestination.name) !== null && _a !== void 0 ? _a : installationName)
@@ -556,9 +543,29 @@ const ElementInstallConfirmation = ({ state }) => {
556
543
  from: mode === 'new-composition' ? null : request.from,
557
544
  overwriteExisting,
558
545
  position: mode === 'new-composition' ? null : request.position,
546
+ undoRedoNavigation: mode === 'new-composition'
547
+ ? {
548
+ undoRoute: (0, url_state_1.getRoute)(),
549
+ redoRoute: `/${newCompositionId}`,
550
+ }
551
+ : null,
552
+ newComposition: mode === 'new-composition'
553
+ ? {
554
+ codemod: newCompositionCodemod,
555
+ symbolicatedStack: selectedFolderStack === null ? null : folderSymbolicatedStack,
556
+ }
557
+ : null,
559
558
  });
560
- if (installed)
559
+ if (installed) {
560
+ if (mode === 'new-composition') {
561
+ selectComposition({
562
+ id: newCompositionId,
563
+ folderName: newCompositionValues.folder.folderName,
564
+ parentFolderName: newCompositionValues.folder.parentName,
565
+ }, true);
566
+ }
561
567
  onClose();
568
+ }
562
569
  else {
563
570
  setSubmitting(false);
564
571
  setRefreshPlan((value) => value + 1);
@@ -566,19 +573,20 @@ const ElementInstallConfirmation = ({ state }) => {
566
573
  }, [
567
574
  activePlan,
568
575
  existingDestination,
569
- compositionAlreadyCreated,
570
- creationKey,
571
576
  installationName,
572
577
  overwriteExisting,
573
578
  canSubmit,
574
- createComposition,
575
579
  folderSymbolicatedStack,
576
580
  mode,
581
+ newCompositionCodemod,
577
582
  newCompositionId,
578
583
  onClose,
579
584
  request,
580
585
  selectedFolderStack,
581
586
  selectedPlan,
587
+ selectComposition,
588
+ newCompositionValues.folder.folderName,
589
+ newCompositionValues.folder.parentName,
582
590
  ]);
583
591
  const cancel = (0, react_1.useCallback)(() => {
584
592
  if (!submitting) {
@@ -623,7 +631,7 @@ const ElementInstallConfirmation = ({ state }) => {
623
631
  ] }), currentPlan === null ? (jsx_runtime_1.jsxs("div", { style: warningStyle, role: "status", children: [
624
632
  jsx_runtime_1.jsx(ValidationMessage_1.WarningTriangle, { style: warningIconStyle }), jsx_runtime_1.jsxs("p", { style: warningDescriptionStyle, children: ["Studio could not find a safe place in \u201C", request.compositionId, "\u201D to insert the Element. Install it into a new composition instead."] })
625
633
  ] })) : null, mode === 'new-composition' ? (jsx_runtime_1.jsxs("section", { style: { ...sectionStyle, marginInline: -16 }, "aria-label": "New composition settings", children: [
626
- jsx_runtime_1.jsx(NewComposition_1.NewCompositionFields, { compositionId: newCompositionId, heightValidationMessage: heightValidationMessage, inputRef: inputRef, nameValidationMessage: compositionAlreadyCreated ? null : nameValidationMessage, setValues: setNewCompositionValues, values: newCompositionValues, widthValidationMessage: widthValidationMessage }), (activeNewCompositionPlanState === null || activeNewCompositionPlanState === void 0 ? void 0 : activeNewCompositionPlanState.type) === 'error' ? (jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: activeNewCompositionPlanState.reason, type: "error" })) : null] })) : null, jsx_runtime_1.jsx("section", { style: sectionStyle, "aria-label": "Element implementation", children: existingDestination ? (jsx_runtime_1.jsxs("div", { role: "radiogroup", "aria-label": "Existing Element file", style: sectionStyle, children: [
634
+ jsx_runtime_1.jsx(NewComposition_1.NewCompositionFields, { compositionId: newCompositionId, heightValidationMessage: heightValidationMessage, inputRef: inputRef, nameValidationMessage: nameValidationMessage, setValues: setNewCompositionValues, values: newCompositionValues, widthValidationMessage: widthValidationMessage }), (activeNewCompositionPlanState === null || activeNewCompositionPlanState === void 0 ? void 0 : activeNewCompositionPlanState.type) === 'error' ? (jsx_runtime_1.jsx(ValidationMessage_1.ValidationMessage, { align: "flex-start", message: activeNewCompositionPlanState.reason, type: "error" })) : null] })) : null, jsx_runtime_1.jsx("section", { style: sectionStyle, "aria-label": "Element implementation", children: existingDestination ? (jsx_runtime_1.jsxs("div", { role: "radiogroup", "aria-label": "Existing Element file", style: sectionStyle, children: [
627
635
  jsx_runtime_1.jsx(RadioButton_1.RadioButton, { checked: !overwriteExisting, disabled: submitting, onClick: () => setInput((previous) => ({ ...previous, overwritePlan: null })), children: "Create a copy" }), !overwriteExisting ? (jsx_runtime_1.jsxs("div", { style: {
628
636
  ...sectionStyle,
629
637
  paddingLeft: 28,
@@ -42,6 +42,6 @@ const FullScreenToggle = ({ hidden }) => {
42
42
  f.unregister();
43
43
  };
44
44
  }, [keybindings, onClick]);
45
- return hidden ? (jsx_runtime_1.jsx("button", { id: "fullscreen-toggle", type: "button", style: { display: 'none' }, onClick: onClick })) : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: accessibilityLabel, shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { id: "fullscreen-toggle", title: "", "aria-label": accessibilityLabel, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaKeyShortcuts || undefined, onClick: onClick, children: (color) => (jsx_runtime_1.jsx(fullscreen_1.FullscreenIcon, { color: color, style: { width: 18, height: 18 } })) }) }));
45
+ return hidden ? (jsx_runtime_1.jsx("button", { id: "fullscreen-toggle", type: "button", style: { display: 'none' }, onClick: onClick })) : (jsx_runtime_1.jsx(ActionTooltip_1.ActionTooltip, { label: "Fullscreen", shortcut: shortcutsDisabled ? null : shortcut, delay: 800, dismissOnClick: true, children: jsx_runtime_1.jsx(ControlButton_1.ControlButton, { id: "fullscreen-toggle", title: "", "aria-label": accessibilityLabel, "aria-keyshortcuts": shortcutsDisabled ? undefined : ariaKeyShortcuts || undefined, onClick: onClick, children: (color) => (jsx_runtime_1.jsx(fullscreen_1.FullscreenIcon, { color: color, style: { width: 18, height: 18 } })) }) }));
46
46
  };
47
47
  exports.FullScreenToggle = FullScreenToggle;
@@ -5,6 +5,7 @@ const react_1 = require("react");
5
5
  const remotion_1 = require("remotion");
6
6
  const calculate_timeline_1 = require("../helpers/calculate-timeline");
7
7
  const get_preview_file_type_1 = require("../helpers/get-preview-file-type");
8
+ const pick_color_1 = require("../helpers/pick-color");
8
9
  const studio_runtime_config_1 = require("../helpers/studio-runtime-config");
9
10
  const timeline_node_path_key_1 = require("../helpers/timeline-node-path-key");
10
11
  const use_keybinding_1 = require("../helpers/use-keybinding");
@@ -184,6 +185,18 @@ const GlobalKeybindings = () => {
184
185
  preventDefault: true,
185
186
  })
186
187
  : null;
188
+ const colorPicker = 'EyeDropper' in window
189
+ ? keybindings.registerKeybinding({
190
+ event: 'keydown',
191
+ action: 'pickColor',
192
+ callback: () => {
193
+ (0, pick_color_1.pickColor)();
194
+ },
195
+ triggerIfInputFieldFocused: false,
196
+ keepRegisteredWhenNotHighestContext: false,
197
+ preventDefault: true,
198
+ })
199
+ : null;
187
200
  const sequencePropKeys = sequencePropShortcuts.map(({ action, fieldKey }) => keybindings.registerKeybinding({
188
201
  event: 'keydown',
189
202
  action,
@@ -274,6 +287,7 @@ const GlobalKeybindings = () => {
274
287
  cmdKKey.unregister();
275
288
  cmdSKey.unregister();
276
289
  cmdIKey === null || cmdIKey === void 0 ? void 0 : cmdIKey.unregister();
290
+ colorPicker === null || colorPicker === void 0 ? void 0 : colorPicker.unregister();
277
291
  pageDown.unregister();
278
292
  pageUp.unregister();
279
293
  shiftMKey.unregister();
@@ -69,6 +69,6 @@ const InspectorLocationCopy = ({ children, location, name, openInEditorLocation
69
69
  opacity: showAction ? 1 : 0,
70
70
  pointerEvents: showAction ? 'auto' : 'none',
71
71
  }, children: [
72
- jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { locationType: null, contextForAgents: contextForAgents, location: openInEditorLocation }), contextForAgents ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopy, renderAction: renderCopyAction, title: "Copy context for agents" })) : null] })) : null] }));
72
+ jsx_runtime_1.jsx(InspectorOpenInEditor_1.InspectorOpenInEditor, { locationType: null, contextForAgents: contextForAgents, location: openInEditorLocation, showTooltips: false }), contextForAgents ? (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { variant: null, onClick: onCopy, renderAction: renderCopyAction, title: "Copy context for agents" })) : null] })) : null] }));
73
73
  };
74
74
  exports.InspectorLocationCopy = InspectorLocationCopy;
@@ -5,4 +5,5 @@ export declare const InspectorOpenInEditor: React.FC<{
5
5
  readonly location: OriginalPosition | null;
6
6
  readonly label?: React.ReactNode;
7
7
  readonly locationType: 'file' | 'folder' | null;
8
+ readonly showTooltips: boolean;
8
9
  }>;