@remotion/studio 4.0.481 → 4.0.482

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 (30) hide show
  1. package/dist/components/Editor.js +1 -1
  2. package/dist/components/GlobalKeybindings.js +1 -1
  3. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +3 -2
  4. package/dist/components/MediaVolumeProvider.js +4 -4
  5. package/dist/components/Modals.js +2 -1
  6. package/dist/components/NewComposition/CodemodFooter.d.ts +1 -0
  7. package/dist/components/NewComposition/CodemodFooter.js +25 -3
  8. package/dist/components/NewComposition/InputDragger.d.ts +4 -0
  9. package/dist/components/NewComposition/InputDragger.js +18 -2
  10. package/dist/components/NewComposition/NewComposition.d.ts +2 -0
  11. package/dist/components/NewComposition/NewComposition.js +178 -0
  12. package/dist/components/PreviewToolbar.js +3 -3
  13. package/dist/components/SelectedOutlineOverlay.d.ts +6 -0
  14. package/dist/components/SelectedOutlineOverlay.js +18 -2
  15. package/dist/components/Timeline/TimelineSelection.d.ts +6 -3
  16. package/dist/components/Timeline/TimelineSelection.js +81 -36
  17. package/dist/components/Timeline/TimelineSequenceItem.js +1 -3
  18. package/dist/components/Timeline/timeline-field-display-utils.js +3 -0
  19. package/dist/components/composition-menu-items.js +17 -0
  20. package/dist/esm/{chunk-4rq5gt8c.js → chunk-nkqfa5bw.js} +1598 -1182
  21. package/dist/esm/internals.mjs +1598 -1182
  22. package/dist/esm/previewEntry.mjs +1605 -1189
  23. package/dist/esm/renderEntry.mjs +1 -1
  24. package/dist/helpers/calculate-timeline.js +6 -2
  25. package/dist/helpers/get-sequence-visible-range.d.ts +1 -0
  26. package/dist/helpers/get-sequence-visible-range.js +15 -1
  27. package/dist/state/modals.d.ts +2 -0
  28. package/package.json +11 -11
  29. package/dist/components/Timeline/TimelineItemStack.d.ts +0 -5
  30. package/dist/components/Timeline/TimelineItemStack.js +0 -29
@@ -266,7 +266,7 @@ const TimelineSelectionOrderProvider = ({ children, items }) => {
266
266
  };
267
267
  exports.TimelineSelectionOrderProvider = TimelineSelectionOrderProvider;
268
268
  const CurrentTimelineSelectionContext = (0, react_1.createContext)(null);
269
- const TIMELINE_SELECTION_FOCUS_PADDING = 8;
269
+ const TIMELINE_SELECTION_REVEAL_RETRY_COUNT = 2;
270
270
  const parseEffectIndex = (effectIndex) => {
271
271
  const parsed = Number(effectIndex);
272
272
  if (!Number.isInteger(parsed) || parsed < 0) {
@@ -557,11 +557,13 @@ const TimelineSelectionProvider = ({ children }) => {
557
557
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
558
558
  const marqueeRegistrationCounter = (0, react_1.useRef)(0);
559
559
  const focusableItems = (0, react_1.useRef)(new Map());
560
- const previousSingleSelectionKey = (0, react_1.useRef)(null);
560
+ const focusableRegistrationCounter = (0, react_1.useRef)(0);
561
+ const [revealRequest, setRevealRequest] = (0, react_1.useState)(null);
561
562
  (0, react_1.useEffect)(() => {
562
563
  if (!canSelect) {
563
564
  selectionScope.current = null;
564
565
  selectionAnchor.current = null;
566
+ setRevealRequest(null);
565
567
  setSelectedItems([]);
566
568
  }
567
569
  }, [canSelect]);
@@ -577,37 +579,62 @@ const TimelineSelectionProvider = ({ children }) => {
577
579
  }, [timelineSelectionScope]);
578
580
  const availableSelectionState = getCurrentAvailableSelectionState(selectedItems);
579
581
  const availableSelectedItems = availableSelectionState.selectedItems;
580
- (0, react_1.useEffect)(() => {
581
- if (availableSelectedItems.length !== 1) {
582
- previousSingleSelectionKey.current = null;
583
- return;
584
- }
585
- const selectedKey = (0, exports.getTimelineSelectionKey)(availableSelectedItems[0]);
586
- if (previousSingleSelectionKey.current === selectedKey) {
587
- return;
588
- }
589
- previousSingleSelectionKey.current = selectedKey;
590
- const animationFrame = requestAnimationFrame(() => {
582
+ const revealSelectionKey = (0, react_1.useCallback)((selectedKey) => {
583
+ let cancelled = false;
584
+ let animationFrame = null;
585
+ const reveal = (attempt) => {
591
586
  var _a;
592
- const registered = (_a = focusableItems.current.get(selectedKey)) !== null && _a !== void 0 ? _a : marqueeSelectableItems.current.get(selectedKey);
587
+ var _b;
588
+ if (cancelled) {
589
+ return;
590
+ }
593
591
  const scrollParent = timeline_refs_1.timelineVerticalScroll.current;
594
- const rect = registered === null || registered === void 0 ? void 0 : registered.getRect();
592
+ const focusableRegistrations = focusableItems.current.get(selectedKey);
593
+ const focusableElement = scrollParent && focusableRegistrations
594
+ ? [...focusableRegistrations.values()]
595
+ .sort((a, b) => a.order - b.order)
596
+ .map((registered) => registered.getElement())
597
+ .find((element) => element !== null && scrollParent.contains(element))
598
+ : null;
599
+ const rect = (_b = focusableElement === null || focusableElement === void 0 ? void 0 : focusableElement.getBoundingClientRect()) !== null && _b !== void 0 ? _b : (_a = marqueeSelectableItems.current.get(selectedKey)) === null || _a === void 0 ? void 0 : _a.getRect();
595
600
  if (!scrollParent || !rect) {
601
+ if (attempt < TIMELINE_SELECTION_REVEAL_RETRY_COUNT) {
602
+ animationFrame = requestAnimationFrame(() => reveal(attempt + 1));
603
+ }
596
604
  return;
597
605
  }
598
606
  const parentRect = scrollParent.getBoundingClientRect();
599
- if (rect.top < parentRect.top) {
600
- scrollParent.scrollTop -=
601
- parentRect.top - rect.top + TIMELINE_SELECTION_FOCUS_PADDING;
607
+ if (rect.top >= parentRect.top && rect.bottom <= parentRect.bottom) {
602
608
  return;
603
609
  }
604
- if (rect.bottom > parentRect.bottom) {
605
- scrollParent.scrollTop +=
606
- rect.bottom - parentRect.bottom + TIMELINE_SELECTION_FOCUS_PADDING;
610
+ const elementCenter = rect.top + rect.height / 2;
611
+ const parentCenter = parentRect.top + parentRect.height / 2;
612
+ scrollParent.scrollTop += elementCenter - parentCenter;
613
+ };
614
+ animationFrame = requestAnimationFrame(() => reveal(0));
615
+ return () => {
616
+ cancelled = true;
617
+ if (animationFrame !== null) {
618
+ cancelAnimationFrame(animationFrame);
607
619
  }
620
+ };
621
+ }, []);
622
+ (0, react_1.useEffect)(() => {
623
+ if (revealRequest === null) {
624
+ return;
625
+ }
626
+ return revealSelectionKey(revealRequest.key);
627
+ }, [revealRequest, revealSelectionKey]);
628
+ const requestRevealSelectionItem = (0, react_1.useCallback)((item) => {
629
+ const key = (0, exports.getTimelineSelectionKey)(item);
630
+ setRevealRequest((previousRequest) => {
631
+ var _a;
632
+ return ({
633
+ key,
634
+ token: ((_a = previousRequest === null || previousRequest === void 0 ? void 0 : previousRequest.token) !== null && _a !== void 0 ? _a : 0) + 1,
635
+ });
608
636
  });
609
- return () => cancelAnimationFrame(animationFrame);
610
- }, [availableSelectedItems]);
637
+ }, []);
611
638
  const expandParentsForSelectionItems = (0, react_1.useCallback)((items) => {
612
639
  for (const item of items) {
613
640
  if (item.type === 'guide') {
@@ -646,11 +673,14 @@ const TimelineSelectionProvider = ({ children }) => {
646
673
  const selectItem = (0, react_1.useCallback)((item, interaction = {
647
674
  shiftKey: false,
648
675
  toggleKey: false,
649
- }, allSelectableItems = []) => {
676
+ }, allSelectableItems = [], options = {}) => {
650
677
  if (!canSelectItem(item)) {
651
678
  return;
652
679
  }
653
680
  expandParentsForSelectionItem(item);
681
+ if (options.reveal) {
682
+ requestRevealSelectionItem(item);
683
+ }
654
684
  setSelectedItems((currentSelectedItems) => {
655
685
  const currentSelectionState = getCurrentAvailableSelectionState(currentSelectedItems);
656
686
  const nextState = (0, exports.getTimelineSelectionAfterInteraction)({
@@ -670,9 +700,10 @@ const TimelineSelectionProvider = ({ children }) => {
670
700
  canSelectItem,
671
701
  expandParentsForSelectionItem,
672
702
  getCurrentAvailableSelectionState,
703
+ requestRevealSelectionItem,
673
704
  timelineSelectionScope,
674
705
  ]);
675
- const selectItems = (0, react_1.useCallback)((items) => {
706
+ const selectItems = (0, react_1.useCallback)((items, options = {}) => {
676
707
  if (!items.every(canSelectItem)) {
677
708
  return;
678
709
  }
@@ -680,8 +711,16 @@ const TimelineSelectionProvider = ({ children }) => {
680
711
  selectionAnchor.current =
681
712
  items.length === 0 ? null : items[items.length - 1];
682
713
  expandParentsForSelectionItems(items);
714
+ if (options.reveal && items.length === 1) {
715
+ requestRevealSelectionItem(items[0]);
716
+ }
683
717
  setSelectedItems(items);
684
- }, [canSelectItem, expandParentsForSelectionItems, timelineSelectionScope]);
718
+ }, [
719
+ canSelectItem,
720
+ expandParentsForSelectionItems,
721
+ requestRevealSelectionItem,
722
+ timelineSelectionScope,
723
+ ]);
685
724
  const registerMarqueeSelectableItem = (0, react_1.useCallback)((item, getRect) => {
686
725
  const key = (0, exports.getTimelineSelectionKey)(item);
687
726
  const registrationOrder = marqueeRegistrationCounter.current;
@@ -695,13 +734,23 @@ const TimelineSelectionProvider = ({ children }) => {
695
734
  marqueeSelectableItems.current.delete(key);
696
735
  };
697
736
  }, []);
698
- const registerFocusableItem = (0, react_1.useCallback)((item, getRect) => {
737
+ const registerFocusableItem = (0, react_1.useCallback)((item, getElement) => {
738
+ var _a;
699
739
  const key = (0, exports.getTimelineSelectionKey)(item);
700
- focusableItems.current.set(key, {
701
- getRect,
740
+ const registrationOrder = focusableRegistrationCounter.current;
741
+ focusableRegistrationCounter.current += 1;
742
+ const registrations = (_a = focusableItems.current.get(key)) !== null && _a !== void 0 ? _a : new Map();
743
+ registrations.set(registrationOrder, {
744
+ getElement,
745
+ order: registrationOrder,
702
746
  });
747
+ focusableItems.current.set(key, registrations);
703
748
  return () => {
704
- focusableItems.current.delete(key);
749
+ const latestRegistrations = focusableItems.current.get(key);
750
+ latestRegistrations === null || latestRegistrations === void 0 ? void 0 : latestRegistrations.delete(registrationOrder);
751
+ if ((latestRegistrations === null || latestRegistrations === void 0 ? void 0 : latestRegistrations.size) === 0) {
752
+ focusableItems.current.delete(key);
753
+ }
705
754
  };
706
755
  }, []);
707
756
  const getMarqueeSelectionForRect = (0, react_1.useCallback)((marqueeRect, lockedSelectionKind) => {
@@ -902,11 +951,7 @@ const useTimelineFocusableItem = (item, ref) => {
902
951
  if (item === null) {
903
952
  return;
904
953
  }
905
- return registerFocusableItem(item, () => {
906
- var _a;
907
- var _b;
908
- return (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) !== null && _b !== void 0 ? _b : null;
909
- });
954
+ return registerFocusableItem(item, () => ref.current);
910
955
  }, [item, ref, registerFocusableItem]);
911
956
  };
912
957
  exports.useTimelineFocusableItem = useTimelineFocusableItem;
@@ -919,7 +964,7 @@ const useTimelineRowSelection = (nodePathInfo) => {
919
964
  if (selectionItem === null) {
920
965
  return;
921
966
  }
922
- selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
967
+ selectItem(selectionItem, interaction, selectableTimelineItemsRef.current, { reveal: true });
923
968
  }, [selectItem, selectableTimelineItemsRef, selectionItem]);
924
969
  return {
925
970
  onSelect,
@@ -57,7 +57,6 @@ const save_sequence_prop_1 = require("./save-sequence-prop");
57
57
  const timeline_asset_link_1 = require("./timeline-asset-link");
58
58
  const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
59
59
  const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
60
- const TimelineItemStack_1 = require("./TimelineItemStack");
61
60
  const TimelineLayerEye_1 = require("./TimelineLayerEye");
62
61
  const TimelineMediaInfo_1 = require("./TimelineMediaInfo");
63
62
  const TimelineRowChrome_1 = require("./TimelineRowChrome");
@@ -807,8 +806,7 @@ const TimelineSequenceItem = ({ nestedDepth, sequence, nodePathInfo, keyframeDis
807
806
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }),
808
807
  " ",
809
808
  jsx_runtime_1.jsx(TimelineMediaInfo_1.TimelineMediaInfo, { src: mediaSrc })
810
- ] })) : null, jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(TimelineItemStack_1.TimelineItemStack, { originalLocation: originalLocation })
811
- ] }) }));
809
+ ] })) : null] }) }));
812
810
  const draggableTrackRow = canHandleSequenceDrag ? (jsx_runtime_1.jsxs("div", { draggable: canReorderSequence, onDragStart: onSequenceDragStart, onDragEnd: onSequenceDragEnd, onDragOver: onSequenceDragOver, onDragLeave: onSequenceDragLeave, onDrop: onSequenceDrop, style: sequenceReorderWrapper, children: [sequenceReorderLineStyle ? (jsx_runtime_1.jsx("div", { style: sequenceReorderLineStyle })) : null, sequenceDropRejection ? (jsx_runtime_1.jsx("div", { style: sequenceReorderRejectionStyle, children: sequenceDropRejection })) : null, trackRow] })) : (trackRow);
813
811
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selectable ? onSelect : null, children: draggableTrackRow })) : (draggableTrackRow), previewConnected &&
814
812
  isExpanded &&
@@ -214,6 +214,9 @@ const formatTimelineFieldValueForDisplay = ({ fieldSchema, value, }) => {
214
214
  if (!fieldSchema) {
215
215
  return formatUnknownTimelineValueForDisplay(value);
216
216
  }
217
+ if (value === undefined) {
218
+ return 'unset';
219
+ }
217
220
  switch (fieldSchema.type) {
218
221
  case 'number':
219
222
  return ((_a = formatNumberTimelineFieldValueForDisplay({ fieldSchema, value })) !== null && _a !== void 0 ? _a : formatUnknownTimelineValueForDisplay(value));
@@ -99,6 +99,23 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
99
99
  id: 'show-in-editor-divider',
100
100
  }
101
101
  : null,
102
+ {
103
+ id: 'new',
104
+ keyHint: null,
105
+ label: `New...`,
106
+ leftItem: null,
107
+ onClick: () => {
108
+ closeMenu();
109
+ setSelectedModal({
110
+ type: 'new-comp',
111
+ });
112
+ },
113
+ quickSwitcherLabel: 'New composition...',
114
+ subMenu: null,
115
+ type: 'item',
116
+ value: 'new',
117
+ disabled: readOnlyStudio,
118
+ },
102
119
  {
103
120
  id: 'rename',
104
121
  keyHint: null,