@remotion/studio 4.0.482 → 4.0.484

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 (77) hide show
  1. package/dist/components/Canvas.js +19 -0
  2. package/dist/components/ColorPicker/ColorPicker.js +65 -3
  3. package/dist/components/ColorPicker/ColorPickerPopup.d.ts +1 -0
  4. package/dist/components/ColorPicker/ColorPickerPopup.js +3 -2
  5. package/dist/components/InspectorPanel/EasingInspector.js +184 -10
  6. package/dist/components/InspectorPanel/KeyframeEasingNavigator.d.ts +14 -0
  7. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +146 -0
  8. package/dist/components/InspectorPanel/KeyframeInspector.d.ts +1 -1
  9. package/dist/components/InspectorPanel/KeyframeInspector.js +228 -5
  10. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +17 -0
  11. package/dist/components/InspectorPanel/SequenceInspectorHeader.js +93 -0
  12. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -58
  13. package/dist/components/InspectorPanel/common.d.ts +12 -0
  14. package/dist/components/InspectorPanel/common.js +78 -1
  15. package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +14 -0
  16. package/dist/components/InspectorPanel/easing-inspector-selection.js +18 -0
  17. package/dist/components/InspectorPanel/keyframe-easing-navigator-items.d.ts +24 -0
  18. package/dist/components/InspectorPanel/keyframe-easing-navigator-items.js +40 -0
  19. package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +8 -0
  20. package/dist/components/InspectorPanel/keyframe-inspector-frame.js +14 -0
  21. package/dist/components/InspectorPanel/styles.d.ts +1 -0
  22. package/dist/components/InspectorPanel/styles.js +9 -1
  23. package/dist/components/InspectorSequenceSection.js +47 -10
  24. package/dist/components/Preview.js +1 -1
  25. package/dist/components/SelectedOutlineOverlay.d.ts +2 -0
  26. package/dist/components/SelectedOutlineOverlay.js +33 -12
  27. package/dist/components/SelectedOutlineUvControls.js +461 -2
  28. package/dist/components/Timeline/EasingEditorModal.js +48 -5
  29. package/dist/components/Timeline/Timeline.js +2 -1
  30. package/dist/components/Timeline/TimelineDeleteKeybindings.js +11 -1
  31. package/dist/components/Timeline/TimelineEffectItem.js +8 -5
  32. package/dist/components/Timeline/TimelineEffectPropItem.js +82 -1
  33. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +2 -2
  34. package/dist/components/Timeline/TimelineKeyframeControls.js +37 -7
  35. package/dist/components/Timeline/TimelineKeyframeEasingLine.d.ts +4 -0
  36. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +12 -6
  37. package/dist/components/Timeline/TimelineKeyframedValue.js +1 -0
  38. package/dist/components/Timeline/TimelineRowChrome.js +6 -4
  39. package/dist/components/Timeline/TimelineSelection.d.ts +7 -1
  40. package/dist/components/Timeline/TimelineSelection.js +19 -3
  41. package/dist/components/Timeline/TimelineSequence.js +20 -8
  42. package/dist/components/Timeline/TimelineSequenceItem.js +64 -28
  43. package/dist/components/Timeline/TimelineSequenceName.d.ts +1 -0
  44. package/dist/components/Timeline/TimelineSequenceName.js +7 -6
  45. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +1 -1
  46. package/dist/components/Timeline/TimelineSequencePropItem.js +80 -1
  47. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +40 -1
  48. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +308 -1
  49. package/dist/components/Timeline/TimelineSlider.js +17 -3
  50. package/dist/components/Timeline/TimelineTrack.js +2 -4
  51. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +8 -2
  52. package/dist/components/Timeline/delete-selected-timeline-item.js +80 -1
  53. package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +18 -0
  54. package/dist/components/Timeline/get-animation-item-selection-for-frame.js +49 -0
  55. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +15 -0
  56. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +26 -0
  57. package/dist/components/Timeline/save-sequence-prop.js +2 -0
  58. package/dist/components/Timeline/should-subscribe-to-sequence-props.d.ts +4 -0
  59. package/dist/components/Timeline/should-subscribe-to-sequence-props.js +10 -0
  60. package/dist/components/Timeline/update-selected-easing.d.ts +1 -0
  61. package/dist/components/Timeline/update-selected-easing.js +4 -3
  62. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +2 -1
  63. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +19 -13
  64. package/dist/components/element-drag-and-drop.d.ts +3 -0
  65. package/dist/components/element-drag-and-drop.js +30 -0
  66. package/dist/components/import-assets.d.ts +11 -0
  67. package/dist/components/import-assets.js +23 -1
  68. package/dist/components/selected-outline-uv.d.ts +71 -1
  69. package/dist/components/selected-outline-uv.js +332 -10
  70. package/dist/esm/{chunk-nkqfa5bw.js → chunk-9erwh79m.js} +11896 -9019
  71. package/dist/esm/internals.mjs +11896 -9019
  72. package/dist/esm/previewEntry.mjs +11923 -9046
  73. package/dist/esm/renderEntry.mjs +1 -1
  74. package/dist/helpers/timeline-layout.d.ts +3 -3
  75. package/dist/helpers/timeline-layout.js +3 -1
  76. package/dist/helpers/use-menu-structure.js +0 -14
  77. package/package.json +11 -11
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNavigatorItemPlayheadFrame = exports.getKeyframeEasingNavigatorItems = void 0;
4
+ const getKeyframeEasingNavigatorItems = ({ includeEasings, keyframes, nodePathInfo, }) => {
5
+ return keyframes.flatMap((keyframe, index) => {
6
+ const keyframeItem = {
7
+ type: 'keyframe',
8
+ selection: {
9
+ type: 'keyframe',
10
+ nodePathInfo,
11
+ frame: keyframe.frame,
12
+ },
13
+ };
14
+ const nextKeyframe = keyframes[index + 1];
15
+ if (!includeEasings || !nextKeyframe) {
16
+ return [keyframeItem];
17
+ }
18
+ return [
19
+ keyframeItem,
20
+ {
21
+ type: 'easing',
22
+ selection: {
23
+ type: 'easing',
24
+ nodePathInfo,
25
+ fromFrame: keyframe.frame,
26
+ toFrame: nextKeyframe.frame,
27
+ segmentIndex: index,
28
+ },
29
+ },
30
+ ];
31
+ });
32
+ };
33
+ exports.getKeyframeEasingNavigatorItems = getKeyframeEasingNavigatorItems;
34
+ const getNavigatorItemPlayheadFrame = (item) => {
35
+ if (item.type === 'keyframe') {
36
+ return item.selection.frame;
37
+ }
38
+ return Math.round((item.selection.fromFrame + item.selection.toFrame) / 2);
39
+ };
40
+ exports.getNavigatorItemPlayheadFrame = getNavigatorItemPlayheadFrame;
@@ -0,0 +1,8 @@
1
+ export declare const clampInspectorKeyframeDisplayFrame: ({ durationInFrames, frame, }: {
2
+ readonly durationInFrames: number;
3
+ readonly frame: number;
4
+ }) => number;
5
+ export declare const getInspectorKeyframeSourceFrame: ({ displayFrame, keyframeDisplayOffset, }: {
6
+ readonly displayFrame: number;
7
+ readonly keyframeDisplayOffset: number;
8
+ }) => number;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInspectorKeyframeSourceFrame = exports.clampInspectorKeyframeDisplayFrame = void 0;
4
+ const clampInspectorKeyframeDisplayFrame = ({ durationInFrames, frame, }) => {
5
+ if (durationInFrames <= 0) {
6
+ return 0;
7
+ }
8
+ return Math.min(Math.max(Math.round(frame), 0), durationInFrames - 1);
9
+ };
10
+ exports.clampInspectorKeyframeDisplayFrame = clampInspectorKeyframeDisplayFrame;
11
+ const getInspectorKeyframeSourceFrame = ({ displayFrame, keyframeDisplayOffset, }) => {
12
+ return displayFrame - keyframeDisplayOffset;
13
+ };
14
+ exports.getInspectorKeyframeSourceFrame = getInspectorKeyframeSourceFrame;
@@ -5,6 +5,7 @@ export declare const defaultPropsSection: React.CSSProperties;
5
5
  export declare const visualControlsSection: React.CSSProperties;
6
6
  export declare const compositionSection: React.CSSProperties;
7
7
  export declare const inspectorSectionDivider: React.CSSProperties;
8
+ export declare const sequenceHeaderDivider: React.CSSProperties;
8
9
  export declare const sectionHeader: React.CSSProperties;
9
10
  export declare const sequenceHeader: React.CSSProperties;
10
11
  export declare const sequenceHeaderTitle: React.CSSProperties;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.keyframeEditorValue = exports.keyframeEditorLabel = exports.keyframeEditorRow = exports.detailValue = exports.detailLabel = exports.detailRow = exports.guideDetailsContainer = exports.detailsContainer = exports.centeredMessage = exports.selectedContainer = exports.resolveLinkStyle = exports.defaultPropsWarningMessages = exports.defaultPropsWarningContainer = exports.sectionHeaderEnd = exports.sectionHeaderStart = exports.sectionHeaderTitle = exports.sectionHeaderRow = exports.sequenceHeaderSubtitle = exports.sequenceHeaderTitle = exports.sequenceHeader = exports.sectionHeader = exports.inspectorSectionDivider = exports.compositionSection = exports.visualControlsSection = exports.defaultPropsSection = exports.scrollableContainer = exports.container = void 0;
3
+ exports.keyframeEditorValue = exports.keyframeEditorLabel = exports.keyframeEditorRow = exports.detailValue = exports.detailLabel = exports.detailRow = exports.guideDetailsContainer = exports.detailsContainer = exports.centeredMessage = exports.selectedContainer = exports.resolveLinkStyle = exports.defaultPropsWarningMessages = exports.defaultPropsWarningContainer = exports.sectionHeaderEnd = exports.sectionHeaderStart = exports.sectionHeaderTitle = exports.sectionHeaderRow = exports.sequenceHeaderSubtitle = exports.sequenceHeaderTitle = exports.sequenceHeader = exports.sectionHeader = exports.sequenceHeaderDivider = exports.inspectorSectionDivider = exports.compositionSection = exports.visualControlsSection = exports.defaultPropsSection = exports.scrollableContainer = exports.container = void 0;
4
4
  const colors_1 = require("../../helpers/colors");
5
5
  const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
6
6
  exports.container = {
@@ -31,11 +31,18 @@ exports.compositionSection = {
31
31
  exports.inspectorSectionDivider = {
32
32
  borderBottom: `1px solid ${colors_1.LINE_COLOR}`,
33
33
  };
34
+ exports.sequenceHeaderDivider = {
35
+ backgroundColor: colors_1.LINE_COLOR,
36
+ flexShrink: 0,
37
+ height: 1,
38
+ margin: '4px 0',
39
+ };
34
40
  exports.sectionHeader = {
35
41
  color: colors_1.LIGHT_TEXT,
36
42
  fontSize: 12,
37
43
  fontWeight: 'bold',
38
44
  padding: `8px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
45
+ userSelect: 'none',
39
46
  };
40
47
  exports.sequenceHeader = {
41
48
  backgroundColor: colors_1.BACKGROUND,
@@ -96,6 +103,7 @@ exports.sectionHeaderTitle = {
96
103
  minWidth: 0,
97
104
  overflow: 'hidden',
98
105
  textOverflow: 'ellipsis',
106
+ userSelect: 'none',
99
107
  whiteSpace: 'nowrap',
100
108
  };
101
109
  exports.sectionHeaderStart = {
@@ -1,8 +1,41 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.InspectorSequenceSection = exports.hasSequenceControls = exports.getInspectorSelectableItems = void 0;
4
37
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
38
+ const react_1 = __importStar(require("react"));
6
39
  const client_id_1 = require("../helpers/client-id");
7
40
  const colors_1 = require("../helpers/colors");
8
41
  const timeline_layout_1 = require("../helpers/timeline-layout");
@@ -27,14 +60,8 @@ const emptyState = {
27
60
  lineHeight: 1.4,
28
61
  padding: '0 12px 8px',
29
62
  };
30
- const divider = {
31
- backgroundColor: colors_1.LINE_COLOR,
32
- flexShrink: 0,
33
- height: 1,
34
- margin: '4px 0',
35
- };
36
63
  const controlsEffectsDivider = {
37
- ...divider,
64
+ ...styles_1.sequenceHeaderDivider,
38
65
  margin: '8px 0 4px',
39
66
  };
40
67
  const effectsHeaderTitle = {
@@ -55,6 +82,15 @@ const isEffectsRoot = (node) => {
55
82
  const getInspectorExpansionKey = (nodePathInfo) => {
56
83
  return JSON.stringify(nodePathInfo);
57
84
  };
85
+ const getInspectorControlGroups = (rows) => {
86
+ return timeline_layout_1.SCHEMA_FIELD_GROUPS.map((group) => ({
87
+ ...group,
88
+ rows: rows.filter(({ node }) => {
89
+ var _a;
90
+ return node.kind === 'field' && ((_a = node.field) === null || _a === void 0 ? void 0 : _a.group) === group.id;
91
+ }),
92
+ })).filter((group) => group.rows.length > 0);
93
+ };
58
94
  const getInspectorSelectableItems = (rows) => {
59
95
  return rows.flatMap(({ node }) => {
60
96
  const selection = (0, TimelineSelection_1.getTimelineSelectionFromNodePathInfo)(node.nodePathInfo);
@@ -116,6 +152,7 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
116
152
  }, [getIsExpanded, tree]);
117
153
  const controlSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(controlRows), [controlRows]);
118
154
  const effectSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(effectRows), [effectRows]);
155
+ const controlGroups = (0, react_1.useMemo)(() => getInspectorControlGroups(controlRows), [controlRows]);
119
156
  const { schema } = sequence.controls;
120
157
  const showEffectsSection = nodePathInfo.supportsEffects || effectRows.length > 0;
121
158
  const showControlsEffectsDivider = controlRows.length > 0 && showEffectsSection;
@@ -148,10 +185,10 @@ const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, k
148
185
  };
149
186
  if (controlRows.length === 0 && !showEffectsSection) {
150
187
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
151
- jsx_runtime_1.jsx("div", { style: divider }), jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" })
188
+ jsx_runtime_1.jsx("div", { style: styles_1.sequenceHeaderDivider }), jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" })
152
189
  ] }));
153
190
  }
154
191
  return (jsx_runtime_1.jsxs("div", { style: container, children: [
155
- jsx_runtime_1.jsx("div", { style: divider }), controlRows.length > 0 ? renderSectionHeader('Controls') : null, jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlRows.map(renderRow) }), showEffectsSection ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showControlsEffectsDivider ? (jsx_runtime_1.jsx("div", { style: controlsEffectsDivider })) : null, renderEffectsHeader(), effectRows.length === 0 ? (jsx_runtime_1.jsx("div", { style: emptyState, children: "None" })) : (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) }))] })) : null] }));
192
+ jsx_runtime_1.jsx("div", { style: styles_1.sequenceHeaderDivider }), controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroups.map((group, i) => (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i === 0 ? null : jsx_runtime_1.jsx("div", { style: controlsEffectsDivider }), renderSectionHeader(group.label), group.rows.map(renderRow)] }, group.id))) })) : null, showEffectsSection ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showControlsEffectsDivider ? (jsx_runtime_1.jsx("div", { style: controlsEffectsDivider })) : null, renderEffectsHeader(), effectRows.length === 0 ? (jsx_runtime_1.jsx("div", { style: emptyState, children: "None" })) : (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) }))] })) : null] }));
156
193
  };
157
194
  exports.InspectorSequenceSection = InspectorSequenceSection;
@@ -122,7 +122,7 @@ const CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent,
122
122
  return (jsx_runtime_1.jsx("div", { style: outer, children: jsx_runtime_1.jsx(RenderPreview_1.RenderPreview, { path: canvasContent.displayName, assetMetadata: assetMetadata, getBlob: canvasContent.getBlob }) }));
123
123
  }
124
124
  return (jsx_runtime_1.jsxs("div", { style: outer, children: [
125
- jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { scale: scale })
125
+ jsx_runtime_1.jsx(PortalContainer, { contentDimensions: contentDimensions, scale: scale, xCorrection: xCorrection, yCorrection: yCorrection }), jsx_runtime_1.jsx(SelectedOutlineOverlay_1.SelectedOutlineOverlay, { scale: scale, translationX: previewSize.translation.x, translationY: previewSize.translation.y })
126
126
  ] }));
127
127
  };
128
128
  const PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions }) => {
@@ -11,4 +11,6 @@ export declare const orderOutlinesForRendering: ({ outlines, targetsByKey, }: {
11
11
  }) => readonly SelectedOutline[];
12
12
  export declare const SelectedOutlineOverlay: React.FC<{
13
13
  readonly scale: number;
14
+ readonly translationX: number;
15
+ readonly translationY: number;
14
16
  }>;
@@ -105,7 +105,7 @@ const orderOutlinesForRendering = ({ outlines, targetsByKey, }) => {
105
105
  });
106
106
  };
107
107
  exports.orderOutlinesForRendering = orderOutlinesForRendering;
108
- const SelectedOutlineOverlay = ({ scale }) => {
108
+ const SelectedOutlineOverlay = ({ scale, translationX, translationY }) => {
109
109
  const { selectedItems, selectItem } = (0, TimelineSelection_1.useTimelineSelection)();
110
110
  const { sequences } = (0, react_1.useContext)(remotion_1.Internals.SequenceManager);
111
111
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
@@ -613,28 +613,49 @@ const SelectedOutlineOverlay = ({ scale }) => {
613
613
  }
614
614
  };
615
615
  }, [keybindings, onArrowKeyDown, onArrowKeyUp, saveKeyboardNudgeSession]);
616
- (0, react_1.useEffect)(() => {
617
- if (outlineTargets.length === 0) {
616
+ const updateOutlines = (0, react_1.useCallback)(() => {
617
+ if (overlayRef.current === null || outlineTargets.length === 0) {
618
618
  setOutlines((prevOutlines) => prevOutlines.length === 0 ? prevOutlines : []);
619
619
  return;
620
620
  }
621
+ const nextOutlines = (0, selected_outline_measurement_1.measureOutlines)(overlayRef.current, outlineTargets);
622
+ setOutlines((prevOutlines) => (0, selected_outline_measurement_1.outlinesAreEqual)(prevOutlines, nextOutlines)
623
+ ? prevOutlines
624
+ : nextOutlines);
625
+ }, [outlineTargets]);
626
+ (0, react_1.useLayoutEffect)(() => {
627
+ updateOutlines();
628
+ }, [outlineTargets, scale, translationX, translationY, updateOutlines]);
629
+ (0, react_1.useLayoutEffect)(() => {
630
+ if (outlineTargets.length === 0 || typeof ResizeObserver === 'undefined') {
631
+ return;
632
+ }
621
633
  let animationFrame = null;
622
- const updateOutlines = () => {
623
- if (overlayRef.current) {
624
- const nextOutlines = (0, selected_outline_measurement_1.measureOutlines)(overlayRef.current, outlineTargets);
625
- setOutlines((prevOutlines) => (0, selected_outline_measurement_1.outlinesAreEqual)(prevOutlines, nextOutlines)
626
- ? prevOutlines
627
- : nextOutlines);
634
+ const scheduleUpdate = () => {
635
+ if (animationFrame !== null) {
636
+ return;
628
637
  }
629
- animationFrame = requestAnimationFrame(updateOutlines);
638
+ animationFrame = requestAnimationFrame(() => {
639
+ animationFrame = null;
640
+ updateOutlines();
641
+ });
630
642
  };
631
- updateOutlines();
643
+ const resizeObserver = new ResizeObserver(scheduleUpdate);
644
+ if (overlayRef.current !== null) {
645
+ resizeObserver.observe(overlayRef.current);
646
+ }
647
+ for (const target of outlineTargets) {
648
+ if (target.ref.current !== null) {
649
+ resizeObserver.observe(target.ref.current);
650
+ }
651
+ }
632
652
  return () => {
633
653
  if (animationFrame !== null) {
634
654
  cancelAnimationFrame(animationFrame);
635
655
  }
656
+ resizeObserver.disconnect();
636
657
  };
637
- }, [outlineTargets]);
658
+ }, [outlineTargets, updateOutlines]);
638
659
  if (outlineTargets.length === 0) {
639
660
  return null;
640
661
  }