@remotion/studio 4.0.479 → 4.0.481

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 (57) hide show
  1. package/dist/components/AudioWaveform.js +19 -11
  2. package/dist/components/Button.d.ts +1 -0
  3. package/dist/components/Button.js +2 -2
  4. package/dist/components/CurrentCompositionSideEffects.d.ts +0 -3
  5. package/dist/components/CurrentCompositionSideEffects.js +1 -37
  6. package/dist/components/Editor.js +2 -5
  7. package/dist/components/EditorContent.js +2 -1
  8. package/dist/components/ExpandedTracksProvider.d.ts +1 -0
  9. package/dist/components/ExpandedTracksProvider.js +81 -7
  10. package/dist/components/GlobalKeybindings.d.ts +3 -1
  11. package/dist/components/GlobalKeybindings.js +104 -10
  12. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -3
  13. package/dist/components/InspectorPanel/inspector-selection.d.ts +3 -3
  14. package/dist/components/InspectorPanel/inspector-selection.js +7 -6
  15. package/dist/components/InspectorPanel/styles.d.ts +1 -0
  16. package/dist/components/InspectorPanel/styles.js +19 -1
  17. package/dist/components/InspectorPanel.js +3 -3
  18. package/dist/components/InspectorSequenceSection.d.ts +3 -0
  19. package/dist/components/InspectorSequenceSection.js +12 -2
  20. package/dist/components/KeyboardShortcutsExplainer.js +10 -2
  21. package/dist/components/ResetZoomButton.d.ts +2 -1
  22. package/dist/components/ResetZoomButton.js +5 -1
  23. package/dist/components/SelectedOutlineElement.js +39 -0
  24. package/dist/components/SelectedOutlineOverlay.js +3 -1
  25. package/dist/components/Timeline/Timeline.js +9 -9
  26. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  27. package/dist/components/Timeline/TimelineEffectPropItem.js +1 -1
  28. package/dist/components/Timeline/TimelineExpandArrowButton.js +42 -2
  29. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  30. package/dist/components/Timeline/TimelineExpandedSection.js +8 -9
  31. package/dist/components/Timeline/TimelineRowChrome.d.ts +2 -0
  32. package/dist/components/Timeline/TimelineRowChrome.js +5 -3
  33. package/dist/components/Timeline/TimelineSelection.d.ts +22 -2
  34. package/dist/components/Timeline/TimelineSelection.js +276 -90
  35. package/dist/components/Timeline/TimelineSequenceItem.js +61 -2
  36. package/dist/components/Timeline/TimelineSequencePropItem.js +1 -1
  37. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +6 -4
  38. package/dist/components/Timeline/find-track-for-node-path-info.js +2 -2
  39. package/dist/components/Timeline/get-node-keyframes.d.ts +7 -0
  40. package/dist/components/Timeline/get-node-keyframes.js +26 -1
  41. package/dist/components/Timeline/reset-selected-timeline-props.js +15 -2
  42. package/dist/components/Timeline/timeline-expanded-filter.d.ts +12 -0
  43. package/dist/components/Timeline/timeline-expanded-filter.js +38 -0
  44. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +50 -18
  45. package/dist/components/Timeline/use-timeline-expanded-tree.d.ts +1 -0
  46. package/dist/components/Timeline/use-timeline-expanded-tree.js +27 -0
  47. package/dist/components/Timeline/use-timeline-height.js +51 -7
  48. package/dist/components/Timeline/use-timeline-keyframe-drag.js +12 -6
  49. package/dist/components/TopPanel.js +1 -1
  50. package/dist/components/selected-outline-measurement.js +48 -14
  51. package/dist/error-overlay/remotion-overlay/ErrorLoader.js +8 -1
  52. package/dist/esm/{chunk-fge2mq5p.js → chunk-4rq5gt8c.js} +16552 -15859
  53. package/dist/esm/internals.mjs +16552 -15859
  54. package/dist/esm/previewEntry.mjs +4055 -3360
  55. package/dist/esm/renderEntry.mjs +1 -1
  56. package/dist/helpers/migrate-expanded-tracks-for-subscription-key.js +3 -3
  57. package/package.json +11 -11
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
3
+ exports.useTimelineRowContainsSelection = exports.useTimelineGuideSelection = exports.useTimelineEasingSelection = exports.useTimelineKeyframeSelection = exports.useTimelineRowSelection = exports.useTimelineFocusableItem = exports.useTimelineMarqueeSelectableItem = exports.useTimelineMarqueeSelection = exports.useCurrentTimelineSelectionStateAsRef = exports.TIMELINE_SCRUBBER_ATTR = exports.TIMELINE_MARQUEE_ITEM_ATTR = exports.useTimelineSelection = exports.TimelineSelectionProvider = exports.TimelineSelectableItemsProvider = exports.TimelineSelectAllKeybindings = exports.getTimelineSequenceSelectionKey = exports.getSelectableTimelineItems = exports.getSelectableTimelineSequenceSelections = exports.getTimelineSelectionKey = exports.getTimelineSelectionFromNodePathInfo = exports.TimelineSelectionOrderProvider = exports.getTimelineMarqueeSelection = exports.timelineMarqueeRectsIntersect = exports.getClampedTimelineMarqueePoint = exports.getNormalizedTimelineMarqueeRect = exports.getAvailableTimelineSelectionState = exports.getTimelineSelectionAfterInteraction = exports.EMPTY_TIMELINE_SELECTION_STATE = exports.shouldSelectTimelineRowOnPointerDown = exports.isTimelineSelectionModifierEvent = exports.TIMELINE_TICKS_BACKGROUND = exports.TIMELINE_BACKGROUND = exports.getTimelineSelectedTrackHighlightStyle = exports.getTimelineColor = exports.getTimelineSelectedLabelStyle = exports.TIMELINE_SELECTED_LABEL_HORIZONTAL_PADDING = exports.TIMELINE_SELECTED_LABEL_TEXT = exports.TIMELINE_SELECTED_LABEL_BACKGROUND = exports.TIMELINE_SELECTED_BACKGROUND = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const react_1 = require("react");
@@ -11,6 +11,11 @@ const timeline_layout_1 = require("../../helpers/timeline-layout");
11
11
  const timeline_node_path_key_1 = require("../../helpers/timeline-node-path-key");
12
12
  const use_keybinding_1 = require("../../helpers/use-keybinding");
13
13
  const z_index_1 = require("../../state/z-index");
14
+ const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
15
+ const get_node_keyframes_1 = require("./get-node-keyframes");
16
+ const get_timeline_easing_segments_1 = require("./get-timeline-easing-segments");
17
+ const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
18
+ const timeline_refs_1 = require("./timeline-refs");
14
19
  const TimelineClipboardKeybindings_1 = require("./TimelineClipboardKeybindings");
15
20
  const TimelineDeleteKeybindings_1 = require("./TimelineDeleteKeybindings");
16
21
  exports.TIMELINE_SELECTED_BACKGROUND = '#3B3F42';
@@ -242,8 +247,8 @@ const defaultTimelineSelectionContextValue = {
242
247
  isSelected: () => false,
243
248
  selectItem: () => undefined,
244
249
  selectItems: () => undefined,
245
- registerSelectableItem: () => () => undefined,
246
250
  registerMarqueeSelectableItem: () => () => undefined,
251
+ registerFocusableItem: () => () => undefined,
247
252
  getMarqueeSelection: () => ({
248
253
  lockedSelectionKind: null,
249
254
  selectedItems: [],
@@ -252,7 +257,16 @@ const defaultTimelineSelectionContextValue = {
252
257
  clearSelection: () => undefined,
253
258
  };
254
259
  const TimelineSelectionContext = (0, react_1.createContext)(defaultTimelineSelectionContextValue);
260
+ const EMPTY_SELECTABLE_TIMELINE_ITEMS = [];
261
+ const SelectableTimelineItemsContext = (0, react_1.createContext)({ current: EMPTY_SELECTABLE_TIMELINE_ITEMS });
262
+ const TimelineSelectionOrderProvider = ({ children, items }) => {
263
+ const itemsRef = (0, react_1.useRef)(items);
264
+ itemsRef.current = items;
265
+ return (jsx_runtime_1.jsx(SelectableTimelineItemsContext.Provider, { value: itemsRef, children: children }));
266
+ };
267
+ exports.TimelineSelectionOrderProvider = TimelineSelectionOrderProvider;
255
268
  const CurrentTimelineSelectionContext = (0, react_1.createContext)(null);
269
+ const TIMELINE_SELECTION_FOCUS_PADDING = 8;
256
270
  const parseEffectIndex = (effectIndex) => {
257
271
  const parsed = Number(effectIndex);
258
272
  if (!Number.isInteger(parsed) || parsed < 0) {
@@ -341,6 +355,108 @@ const getSelectableTimelineSequenceSelections = (tracks) => {
341
355
  });
342
356
  };
343
357
  exports.getSelectableTimelineSequenceSelections = getSelectableTimelineSequenceSelections;
358
+ const canEditEasingForInterpolationFunction = (interpolationFunction) => interpolationFunction === 'interpolate' ||
359
+ interpolationFunction === 'interpolateColors';
360
+ const getTimelineTreeNodeCanEditEasing = ({ node, nodePathInfo, propStatuses, }) => {
361
+ var _a;
362
+ if (node.kind !== 'field' || node.field === null) {
363
+ return false;
364
+ }
365
+ if (node.field.kind === 'sequence-field') {
366
+ const sequencePropStatus = (_a = remotion_1.Internals.getPropStatusesCtx(propStatuses, nodePathInfo.sequenceSubscriptionKey)) === null || _a === void 0 ? void 0 : _a[node.field.key];
367
+ return ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) === 'keyframed' &&
368
+ canEditEasingForInterpolationFunction(sequencePropStatus.interpolationFunction));
369
+ }
370
+ const effectStatus = remotion_1.Internals.getEffectPropStatusesCtx({
371
+ propStatuses,
372
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
373
+ effectIndex: node.field.effectIndex,
374
+ });
375
+ const effectPropStatus = effectStatus.type === 'can-update-effect'
376
+ ? effectStatus.props[node.field.key]
377
+ : null;
378
+ return ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) === 'keyframed' &&
379
+ canEditEasingForInterpolationFunction(effectPropStatus.interpolationFunction));
380
+ };
381
+ const getSelectableTimelineItems = ({ getDragOverrides, getEffectDragOverrides, getIsExpanded, propStatuses, selectedItems, timeline, timelinePosition, }) => {
382
+ const selectedRowKeys = (0, timeline_expanded_filter_1.getSelectedTimelineExpandedRowKeys)(selectedItems);
383
+ return timeline.flatMap((track) => {
384
+ const { nodePathInfo } = track;
385
+ if (nodePathInfo === null) {
386
+ return [];
387
+ }
388
+ const sequenceSelection = (0, exports.getTimelineSelectionFromNodePathInfo)(nodePathInfo);
389
+ if (sequenceSelection === null) {
390
+ return [];
391
+ }
392
+ if (!getIsExpanded(nodePathInfo)) {
393
+ return [sequenceSelection];
394
+ }
395
+ const tree = (0, timeline_layout_1.buildTimelineTree)({
396
+ sequence: track.sequence,
397
+ nodePathInfo,
398
+ getDragOverrides,
399
+ getEffectDragOverrides,
400
+ propStatuses,
401
+ });
402
+ const filteredTree = (0, timeline_expanded_filter_1.filterTimelineExpandedTree)({
403
+ nodes: tree,
404
+ shouldShowNode: (node) => (0, timeline_expanded_filter_1.isTimelineExpandedNodeSelected)({
405
+ nodePathInfo: node.nodePathInfo,
406
+ selectedRowKeys,
407
+ }) ||
408
+ (0, get_node_keyframes_1.getNodeHasKeyframes)({
409
+ node,
410
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
411
+ propStatuses,
412
+ getDragOverrides,
413
+ getEffectDragOverrides,
414
+ }),
415
+ });
416
+ const visibleTreeRows = (0, timeline_layout_1.flattenVisibleTreeNodes)({
417
+ nodes: filteredTree,
418
+ getIsExpanded,
419
+ });
420
+ return [
421
+ sequenceSelection,
422
+ ...visibleTreeRows.flatMap(({ node }) => {
423
+ const rowSelection = (0, exports.getTimelineSelectionFromNodePathInfo)(node.nodePathInfo);
424
+ if (rowSelection === null) {
425
+ return [];
426
+ }
427
+ const keyframes = (0, get_node_keyframes_1.getNodeKeyframes)({
428
+ node,
429
+ nodePath: nodePathInfo.sequenceSubscriptionKey,
430
+ propStatuses,
431
+ keyframeDisplayOffset: track.keyframeDisplayOffset,
432
+ getDragOverrides,
433
+ getEffectDragOverrides,
434
+ timelinePosition,
435
+ });
436
+ const keyframeSelections = keyframes.map((keyframe) => ({
437
+ type: 'keyframe',
438
+ nodePathInfo: node.nodePathInfo,
439
+ frame: keyframe.frame,
440
+ }));
441
+ const easingSelections = getTimelineTreeNodeCanEditEasing({
442
+ node,
443
+ nodePathInfo,
444
+ propStatuses,
445
+ })
446
+ ? (0, get_timeline_easing_segments_1.getTimelineEasingSegments)(keyframes).map((segment) => ({
447
+ type: 'easing',
448
+ nodePathInfo: node.nodePathInfo,
449
+ fromFrame: segment.fromFrame,
450
+ toFrame: segment.toFrame,
451
+ segmentIndex: segment.segmentIndex,
452
+ }))
453
+ : [];
454
+ return [rowSelection, ...easingSelections, ...keyframeSelections];
455
+ }),
456
+ ];
457
+ });
458
+ };
459
+ exports.getSelectableTimelineItems = getSelectableTimelineItems;
344
460
  const getTimelineSequenceSelectionKey = (nodePathInfo) => (0, timeline_node_path_key_1.timelineNodePathInfoToKey)({ ...nodePathInfo, auxiliaryKeys: [] });
345
461
  exports.getTimelineSequenceSelectionKey = getTimelineSequenceSelectionKey;
346
462
  const TimelineSelectAllKeybindings = ({ timeline }) => {
@@ -376,25 +492,72 @@ const TimelineSelectAllKeybindings = ({ timeline }) => {
376
492
  return null;
377
493
  };
378
494
  exports.TimelineSelectAllKeybindings = TimelineSelectAllKeybindings;
495
+ const TimelineEscapeKeybindings = () => {
496
+ const keybindings = (0, use_keybinding_1.useKeybinding)();
497
+ const currentSelection = (0, exports.useCurrentTimelineSelectionStateAsRef)();
498
+ (0, react_1.useEffect)(() => {
499
+ const escape = keybindings.registerKeybinding({
500
+ event: 'keydown',
501
+ key: 'Escape',
502
+ callback: (event) => {
503
+ const { selectedItems, clearSelection } = currentSelection.current;
504
+ if (selectedItems.length === 0) {
505
+ return;
506
+ }
507
+ clearSelection();
508
+ event.preventDefault();
509
+ },
510
+ commandCtrlKey: false,
511
+ preventDefault: false,
512
+ triggerIfInputFieldFocused: false,
513
+ keepRegisteredWhenNotHighestContext: false,
514
+ });
515
+ return () => {
516
+ escape.unregister();
517
+ };
518
+ }, [currentSelection, keybindings]);
519
+ return null;
520
+ };
521
+ const TimelineSelectableItemsProvider = ({ children, timeline }) => {
522
+ const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
523
+ const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
524
+ const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
525
+ const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
526
+ const { selectedItems } = (0, exports.useTimelineSelection)();
527
+ const selectableItems = (0, react_1.useMemo)(() => (0, exports.getSelectableTimelineItems)({
528
+ getDragOverrides,
529
+ getEffectDragOverrides,
530
+ getIsExpanded,
531
+ propStatuses,
532
+ selectedItems,
533
+ timeline,
534
+ timelinePosition,
535
+ }), [
536
+ getDragOverrides,
537
+ getEffectDragOverrides,
538
+ getIsExpanded,
539
+ propStatuses,
540
+ selectedItems,
541
+ timeline,
542
+ timelinePosition,
543
+ ]);
544
+ return (jsx_runtime_1.jsx(exports.TimelineSelectionOrderProvider, { items: selectableItems, children: children }));
545
+ };
546
+ exports.TimelineSelectableItemsProvider = TimelineSelectableItemsProvider;
379
547
  const TimelineSelectionProvider = ({ children }) => {
380
548
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
381
549
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
382
550
  const timelineSelectionScope = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
551
+ const { expandParentTracks } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksSetterContext);
383
552
  const canSelect = previewServerState.type === 'connected' &&
384
553
  !window.remotion_isReadOnlyStudio;
385
554
  const [selectedItems, setSelectedItems] = (0, react_1.useState)([]);
386
555
  const selectionAnchor = (0, react_1.useRef)(null);
387
556
  const selectionScope = (0, react_1.useRef)(null);
388
- const selectableItemsOrder = (0, react_1.useRef)(new Map());
389
- const selectableItems = (0, react_1.useRef)(new Map());
390
- const selectableItemRegistrationCounts = (0, react_1.useRef)(new Map());
391
557
  const marqueeSelectableItems = (0, react_1.useRef)(new Map());
392
- const registrationCounter = (0, react_1.useRef)(0);
393
558
  const marqueeRegistrationCounter = (0, react_1.useRef)(0);
394
- const [selectableItemsVersion, setSelectableItemsVersion] = (0, react_1.useState)(0);
395
- const bumpSelectableItemsVersion = (0, react_1.useCallback)(() => {
396
- setSelectableItemsVersion((version) => version + 1);
397
- }, []);
559
+ const focusableItems = (0, react_1.useRef)(new Map());
560
+ const previousSingleSelectionKey = (0, react_1.useRef)(null);
398
561
  (0, react_1.useEffect)(() => {
399
562
  if (!canSelect) {
400
563
  selectionScope.current = null;
@@ -407,28 +570,65 @@ const TimelineSelectionProvider = ({ children }) => {
407
570
  if (selectionScope.current !== timelineSelectionScope) {
408
571
  return exports.EMPTY_TIMELINE_SELECTION_STATE;
409
572
  }
410
- return (0, exports.getAvailableTimelineSelectionState)({
411
- availableKeys: new Set(selectableItems.current.keys()),
412
- availableItemsByKey: selectableItems.current,
413
- state: {
414
- selectedItems: currentSelectedItems,
415
- anchor: selectionAnchor.current,
416
- },
417
- });
573
+ return {
574
+ selectedItems: currentSelectedItems,
575
+ anchor: selectionAnchor.current,
576
+ };
418
577
  }, [timelineSelectionScope]);
419
578
  const availableSelectionState = getCurrentAvailableSelectionState(selectedItems);
420
579
  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(() => {
591
+ var _a;
592
+ const registered = (_a = focusableItems.current.get(selectedKey)) !== null && _a !== void 0 ? _a : marqueeSelectableItems.current.get(selectedKey);
593
+ const scrollParent = timeline_refs_1.timelineVerticalScroll.current;
594
+ const rect = registered === null || registered === void 0 ? void 0 : registered.getRect();
595
+ if (!scrollParent || !rect) {
596
+ return;
597
+ }
598
+ const parentRect = scrollParent.getBoundingClientRect();
599
+ if (rect.top < parentRect.top) {
600
+ scrollParent.scrollTop -=
601
+ parentRect.top - rect.top + TIMELINE_SELECTION_FOCUS_PADDING;
602
+ return;
603
+ }
604
+ if (rect.bottom > parentRect.bottom) {
605
+ scrollParent.scrollTop +=
606
+ rect.bottom - parentRect.bottom + TIMELINE_SELECTION_FOCUS_PADDING;
607
+ }
608
+ });
609
+ return () => cancelAnimationFrame(animationFrame);
610
+ }, [availableSelectedItems]);
611
+ const expandParentsForSelectionItems = (0, react_1.useCallback)((items) => {
612
+ for (const item of items) {
613
+ if (item.type === 'guide') {
614
+ continue;
615
+ }
616
+ expandParentTracks(item.nodePathInfo);
617
+ }
618
+ }, [expandParentTracks]);
619
+ const expandParentsForSelectionItem = (0, react_1.useCallback)((item) => {
620
+ if (item.type === 'guide') {
621
+ return;
622
+ }
623
+ expandParentTracks(item.nodePathInfo);
624
+ }, [expandParentTracks]);
421
625
  (0, react_1.useEffect)(() => {
422
626
  setSelectedItems((currentSelectedItems) => {
423
627
  const nextState = selectionScope.current === timelineSelectionScope
424
- ? (0, exports.getAvailableTimelineSelectionState)({
425
- availableKeys: new Set(selectableItems.current.keys()),
426
- availableItemsByKey: selectableItems.current,
427
- state: {
428
- selectedItems: currentSelectedItems,
429
- anchor: selectionAnchor.current,
430
- },
431
- })
628
+ ? {
629
+ selectedItems: currentSelectedItems,
630
+ anchor: selectionAnchor.current,
631
+ }
432
632
  : exports.EMPTY_TIMELINE_SELECTION_STATE;
433
633
  selectionScope.current = timelineSelectionScope;
434
634
  selectionAnchor.current = nextState.anchor;
@@ -438,7 +638,7 @@ const TimelineSelectionProvider = ({ children }) => {
438
638
  }
439
639
  return nextState.selectedItems;
440
640
  });
441
- }, [selectableItemsVersion, timelineSelectionScope]);
641
+ }, [timelineSelectionScope]);
442
642
  const selectedKeys = (0, react_1.useMemo)(() => new Set(availableSelectedItems.map(exports.getTimelineSelectionKey)), [availableSelectedItems]);
443
643
  const isSelected = (0, react_1.useCallback)((item) => {
444
644
  return selectedKeys.has((0, exports.getTimelineSelectionKey)(item));
@@ -446,19 +646,13 @@ const TimelineSelectionProvider = ({ children }) => {
446
646
  const selectItem = (0, react_1.useCallback)((item, interaction = {
447
647
  shiftKey: false,
448
648
  toggleKey: false,
449
- }) => {
649
+ }, allSelectableItems = []) => {
450
650
  if (!canSelectItem(item)) {
451
651
  return;
452
652
  }
653
+ expandParentsForSelectionItem(item);
453
654
  setSelectedItems((currentSelectedItems) => {
454
655
  const currentSelectionState = getCurrentAvailableSelectionState(currentSelectedItems);
455
- const orderedSelectableItems = [
456
- ...selectableItems.current.values(),
457
- ].sort((a, b) => {
458
- var _a, _b;
459
- return (((_a = selectableItemsOrder.current.get((0, exports.getTimelineSelectionKey)(a))) !== null && _a !== void 0 ? _a : 0) -
460
- ((_b = selectableItemsOrder.current.get((0, exports.getTimelineSelectionKey)(b))) !== null && _b !== void 0 ? _b : 0));
461
- });
462
656
  const nextState = (0, exports.getTimelineSelectionAfterInteraction)({
463
657
  currentState: {
464
658
  selectedItems: currentSelectionState.selectedItems,
@@ -466,13 +660,18 @@ const TimelineSelectionProvider = ({ children }) => {
466
660
  },
467
661
  clickedItem: item,
468
662
  interaction,
469
- allSelectableItems: orderedSelectableItems,
663
+ allSelectableItems,
470
664
  });
471
665
  selectionScope.current = timelineSelectionScope;
472
666
  selectionAnchor.current = nextState.anchor;
473
667
  return nextState.selectedItems;
474
668
  });
475
- }, [canSelectItem, getCurrentAvailableSelectionState, timelineSelectionScope]);
669
+ }, [
670
+ canSelectItem,
671
+ expandParentsForSelectionItem,
672
+ getCurrentAvailableSelectionState,
673
+ timelineSelectionScope,
674
+ ]);
476
675
  const selectItems = (0, react_1.useCallback)((items) => {
477
676
  if (!items.every(canSelectItem)) {
478
677
  return;
@@ -480,33 +679,9 @@ const TimelineSelectionProvider = ({ children }) => {
480
679
  selectionScope.current = timelineSelectionScope;
481
680
  selectionAnchor.current =
482
681
  items.length === 0 ? null : items[items.length - 1];
682
+ expandParentsForSelectionItems(items);
483
683
  setSelectedItems(items);
484
- }, [canSelectItem, timelineSelectionScope]);
485
- const registerSelectableItem = (0, react_1.useCallback)((item) => {
486
- var _a;
487
- const key = (0, exports.getTimelineSelectionKey)(item);
488
- const currentRegistrationCount = (_a = selectableItemRegistrationCounts.current.get(key)) !== null && _a !== void 0 ? _a : 0;
489
- if (currentRegistrationCount === 0) {
490
- const registrationOrder = registrationCounter.current;
491
- registrationCounter.current += 1;
492
- selectableItemsOrder.current.set(key, registrationOrder);
493
- }
494
- selectableItemRegistrationCounts.current.set(key, currentRegistrationCount + 1);
495
- selectableItems.current.set(key, item);
496
- bumpSelectableItemsVersion();
497
- return () => {
498
- var _a;
499
- const nextRegistrationCount = ((_a = selectableItemRegistrationCounts.current.get(key)) !== null && _a !== void 0 ? _a : 1) - 1;
500
- if (nextRegistrationCount > 0) {
501
- selectableItemRegistrationCounts.current.set(key, nextRegistrationCount);
502
- return;
503
- }
504
- selectableItemRegistrationCounts.current.delete(key);
505
- selectableItems.current.delete(key);
506
- selectableItemsOrder.current.delete(key);
507
- bumpSelectableItemsVersion();
508
- };
509
- }, [bumpSelectableItemsVersion]);
684
+ }, [canSelectItem, expandParentsForSelectionItems, timelineSelectionScope]);
510
685
  const registerMarqueeSelectableItem = (0, react_1.useCallback)((item, getRect) => {
511
686
  const key = (0, exports.getTimelineSelectionKey)(item);
512
687
  const registrationOrder = marqueeRegistrationCounter.current;
@@ -520,6 +695,15 @@ const TimelineSelectionProvider = ({ children }) => {
520
695
  marqueeSelectableItems.current.delete(key);
521
696
  };
522
697
  }, []);
698
+ const registerFocusableItem = (0, react_1.useCallback)((item, getRect) => {
699
+ const key = (0, exports.getTimelineSelectionKey)(item);
700
+ focusableItems.current.set(key, {
701
+ getRect,
702
+ });
703
+ return () => {
704
+ focusableItems.current.delete(key);
705
+ };
706
+ }, []);
523
707
  const getMarqueeSelectionForRect = (0, react_1.useCallback)((marqueeRect, lockedSelectionKind) => {
524
708
  const candidates = [...marqueeSelectableItems.current.values()]
525
709
  .sort((a, b) => a.order - b.order)
@@ -564,8 +748,8 @@ const TimelineSelectionProvider = ({ children }) => {
564
748
  isSelected,
565
749
  selectItem,
566
750
  selectItems,
567
- registerSelectableItem,
568
751
  registerMarqueeSelectableItem,
752
+ registerFocusableItem,
569
753
  getMarqueeSelection: getMarqueeSelectionForRect,
570
754
  containsSelection,
571
755
  clearSelection,
@@ -575,15 +759,15 @@ const TimelineSelectionProvider = ({ children }) => {
575
759
  isSelected,
576
760
  selectItem,
577
761
  selectItems,
578
- registerSelectableItem,
579
762
  registerMarqueeSelectableItem,
763
+ registerFocusableItem,
580
764
  getMarqueeSelectionForRect,
581
765
  containsSelection,
582
766
  clearSelection,
583
767
  ]);
584
768
  const currentSelection = (0, react_1.useRef)(value);
585
769
  currentSelection.current = value;
586
- return (jsx_runtime_1.jsx(CurrentTimelineSelectionContext.Provider, { value: currentSelection, children: jsx_runtime_1.jsxs(TimelineSelectionContext.Provider, { value: value, children: [children, jsx_runtime_1.jsx(TimelineClipboardKeybindings_1.TimelineClipboardKeybindings, {}), jsx_runtime_1.jsx(TimelineDeleteKeybindings_1.TimelineDeleteKeybindings, {})
770
+ return (jsx_runtime_1.jsx(CurrentTimelineSelectionContext.Provider, { value: currentSelection, children: jsx_runtime_1.jsxs(TimelineSelectionContext.Provider, { value: value, children: [children, jsx_runtime_1.jsx(TimelineEscapeKeybindings, {}), jsx_runtime_1.jsx(TimelineClipboardKeybindings_1.TimelineClipboardKeybindings, {}), jsx_runtime_1.jsx(TimelineDeleteKeybindings_1.TimelineDeleteKeybindings, {})
587
771
  ] }) }));
588
772
  };
589
773
  exports.TimelineSelectionProvider = TimelineSelectionProvider;
@@ -712,22 +896,31 @@ const useTimelineMarqueeSelectableItem = (item, ref) => {
712
896
  }, [item, ref, registerMarqueeSelectableItem]);
713
897
  };
714
898
  exports.useTimelineMarqueeSelectableItem = useTimelineMarqueeSelectableItem;
715
- const useTimelineRowSelection = (nodePathInfo) => {
716
- const { canSelect, isSelected, selectItem, registerSelectableItem } = (0, exports.useTimelineSelection)();
717
- const selectionItem = (0, react_1.useMemo)(() => (0, exports.getTimelineSelectionFromNodePathInfo)(nodePathInfo), [nodePathInfo]);
899
+ const useTimelineFocusableItem = (item, ref) => {
900
+ const { registerFocusableItem } = (0, exports.useTimelineSelection)();
718
901
  (0, react_1.useEffect)(() => {
719
- if (selectionItem === null) {
902
+ if (item === null) {
720
903
  return;
721
904
  }
722
- return registerSelectableItem(selectionItem);
723
- }, [registerSelectableItem, selectionItem]);
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
+ });
910
+ }, [item, ref, registerFocusableItem]);
911
+ };
912
+ exports.useTimelineFocusableItem = useTimelineFocusableItem;
913
+ const useTimelineRowSelection = (nodePathInfo) => {
914
+ const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
915
+ const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
916
+ const selectionItem = (0, react_1.useMemo)(() => (0, exports.getTimelineSelectionFromNodePathInfo)(nodePathInfo), [nodePathInfo]);
724
917
  const selected = selectionItem === null ? false : isSelected(selectionItem);
725
918
  const onSelect = (0, react_1.useCallback)((interaction) => {
726
919
  if (selectionItem === null) {
727
920
  return;
728
921
  }
729
- selectItem(selectionItem, interaction);
730
- }, [selectItem, selectionItem]);
922
+ selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
923
+ }, [selectItem, selectableTimelineItemsRef, selectionItem]);
731
924
  return {
732
925
  onSelect,
733
926
  selectable: canSelect && selectionItem !== null,
@@ -737,19 +930,17 @@ const useTimelineRowSelection = (nodePathInfo) => {
737
930
  };
738
931
  exports.useTimelineRowSelection = useTimelineRowSelection;
739
932
  const useTimelineKeyframeSelection = (nodePathInfo, frame) => {
740
- const { canSelect, isSelected, selectItem, registerSelectableItem } = (0, exports.useTimelineSelection)();
933
+ const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
934
+ const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
741
935
  const selectionItem = (0, react_1.useMemo)(() => ({
742
936
  type: 'keyframe',
743
937
  nodePathInfo,
744
938
  frame,
745
939
  }), [nodePathInfo, frame]);
746
- (0, react_1.useEffect)(() => {
747
- return registerSelectableItem(selectionItem);
748
- }, [registerSelectableItem, selectionItem]);
749
940
  const selected = isSelected(selectionItem);
750
941
  const onSelect = (0, react_1.useCallback)((interaction) => {
751
- selectItem(selectionItem, interaction);
752
- }, [selectItem, selectionItem]);
942
+ selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
943
+ }, [selectItem, selectableTimelineItemsRef, selectionItem]);
753
944
  return {
754
945
  onSelect,
755
946
  selectable: canSelect,
@@ -759,7 +950,8 @@ const useTimelineKeyframeSelection = (nodePathInfo, frame) => {
759
950
  };
760
951
  exports.useTimelineKeyframeSelection = useTimelineKeyframeSelection;
761
952
  const useTimelineEasingSelection = ({ nodePathInfo, fromFrame, toFrame, segmentIndex, }) => {
762
- const { canSelect, isSelected, selectItem, registerSelectableItem } = (0, exports.useTimelineSelection)();
953
+ const { canSelect, isSelected, selectItem } = (0, exports.useTimelineSelection)();
954
+ const selectableTimelineItemsRef = (0, react_1.useContext)(SelectableTimelineItemsContext);
763
955
  const selectionItem = (0, react_1.useMemo)(() => ({
764
956
  type: 'easing',
765
957
  nodePathInfo,
@@ -767,13 +959,10 @@ const useTimelineEasingSelection = ({ nodePathInfo, fromFrame, toFrame, segmentI
767
959
  toFrame,
768
960
  segmentIndex,
769
961
  }), [nodePathInfo, fromFrame, segmentIndex, toFrame]);
770
- (0, react_1.useEffect)(() => {
771
- return registerSelectableItem(selectionItem);
772
- }, [registerSelectableItem, selectionItem]);
773
962
  const selected = isSelected(selectionItem);
774
963
  const onSelect = (0, react_1.useCallback)((interaction) => {
775
- selectItem(selectionItem, interaction);
776
- }, [selectItem, selectionItem]);
964
+ selectItem(selectionItem, interaction, selectableTimelineItemsRef.current);
965
+ }, [selectItem, selectableTimelineItemsRef, selectionItem]);
777
966
  return {
778
967
  onSelect,
779
968
  selectable: canSelect,
@@ -783,14 +972,11 @@ const useTimelineEasingSelection = ({ nodePathInfo, fromFrame, toFrame, segmentI
783
972
  };
784
973
  exports.useTimelineEasingSelection = useTimelineEasingSelection;
785
974
  const useTimelineGuideSelection = (guideId) => {
786
- const { canSelect, clearSelection, isSelected, selectItem, registerSelectableItem, } = (0, exports.useTimelineSelection)();
975
+ const { canSelect, clearSelection, isSelected, selectItem } = (0, exports.useTimelineSelection)();
787
976
  const selectionItem = (0, react_1.useMemo)(() => ({
788
977
  type: 'guide',
789
978
  guideId,
790
979
  }), [guideId]);
791
- (0, react_1.useEffect)(() => {
792
- return registerSelectableItem(selectionItem);
793
- }, [registerSelectableItem, selectionItem]);
794
980
  const selected = isSelected(selectionItem);
795
981
  const onSelect = (0, react_1.useCallback)(() => {
796
982
  selectItem(selectionItem);