@remotion/studio 4.0.508 → 4.0.510

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 (117) hide show
  1. package/dist/Studio.d.ts +5 -0
  2. package/dist/Studio.js +2 -2
  3. package/dist/components/Canvas.js +41 -8
  4. package/dist/components/ColorPicker/AlphaSlider.js +2 -2
  5. package/dist/components/ColorPicker/HueSlider.js +2 -2
  6. package/dist/components/ColorPicker/SaturationValueArea.js +2 -2
  7. package/dist/components/CompositionSelectorItem.js +1 -1
  8. package/dist/components/EditorGuides/Guide.js +2 -2
  9. package/dist/components/EditorRuler/index.js +2 -2
  10. package/dist/components/ExplorerPanel.js +19 -1
  11. package/dist/components/InspectorOpenInEditor.js +19 -5
  12. package/dist/components/InspectorPanel/CompositionMetadata.js +23 -1
  13. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +3 -3
  14. package/dist/components/Menu/MenuItem.js +2 -2
  15. package/dist/components/ModalContainer.js +1 -1
  16. package/dist/components/Modals.js +2 -9
  17. package/dist/components/NewComposition/InputDragger.js +2 -2
  18. package/dist/components/NewComposition/NewComposition.d.ts +2 -0
  19. package/dist/components/NewComposition/NewComposition.js +38 -6
  20. package/dist/components/NewComposition/get-new-composition-defaults.d.ts +1 -1
  21. package/dist/components/NewComposition/get-new-composition-defaults.js +9 -1
  22. package/dist/components/QuickSwitcher/asset-search.js +1 -0
  23. package/dist/components/SelectedOutlineCanvasRotation.js +6 -4
  24. package/dist/components/SelectedOutlineCropControls.js +3 -3
  25. package/dist/components/SelectedOutlineElement.js +6 -2
  26. package/dist/components/SelectedOutlinePolygon.js +4 -3
  27. package/dist/components/SelectedOutlineRotationCornerHandle.d.ts +5 -0
  28. package/dist/components/SelectedOutlineRotationCornerHandle.js +4 -4
  29. package/dist/components/SelectedOutlineScaleEdgeLine.d.ts +1 -0
  30. package/dist/components/SelectedOutlineScaleEdgeLine.js +4 -4
  31. package/dist/components/SelectedOutlineTransformOriginHandle.js +2 -2
  32. package/dist/components/SelectedOutlineUvControls.js +8 -8
  33. package/dist/components/Splitter/SplitterHandle.js +2 -2
  34. package/dist/components/Tabs/index.d.ts +2 -0
  35. package/dist/components/Tabs/index.js +2 -2
  36. package/dist/components/Timeline/EasingEditorModal.d.ts +8 -0
  37. package/dist/components/Timeline/EasingEditorModal.js +10 -11
  38. package/dist/components/Timeline/SubscribeToNodePaths.js +1 -1
  39. package/dist/components/Timeline/Timeline.js +55 -1
  40. package/dist/components/Timeline/TimelineClipboardKeybindings.js +99 -35
  41. package/dist/components/Timeline/TimelineColorField.js +1 -6
  42. package/dist/components/Timeline/TimelineDragHandler.js +2 -2
  43. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  44. package/dist/components/Timeline/TimelineEffectPropItem.js +8 -1
  45. package/dist/components/Timeline/TimelineEnumField.js +1 -4
  46. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  47. package/dist/components/Timeline/TimelineFieldRowContent.d.ts +2 -1
  48. package/dist/components/Timeline/TimelineFieldRowContent.js +18 -3
  49. package/dist/components/Timeline/TimelineFontFamilyField.js +1 -2
  50. package/dist/components/Timeline/TimelineInOutDragHandler.js +2 -2
  51. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +3 -2
  52. package/dist/components/Timeline/TimelineLayerEye.js +2 -2
  53. package/dist/components/Timeline/TimelineNumberField.js +4 -2
  54. package/dist/components/Timeline/TimelineRotationField.js +3 -3
  55. package/dist/components/Timeline/TimelineRowChrome.d.ts +5 -0
  56. package/dist/components/Timeline/TimelineRowChrome.js +14 -9
  57. package/dist/components/Timeline/TimelineRowLayoutContext.d.ts +1 -0
  58. package/dist/components/Timeline/TimelineRowLayoutContext.js +4 -1
  59. package/dist/components/Timeline/TimelineScaleField.js +4 -0
  60. package/dist/components/Timeline/TimelineSelection.js +2 -2
  61. package/dist/components/Timeline/TimelineSequenceItem.js +2 -25
  62. package/dist/components/Timeline/TimelineSequencePropItem.js +8 -2
  63. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +2 -0
  64. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +69 -20
  65. package/dist/components/Timeline/TimelineTextContentField.js +1 -1
  66. package/dist/components/Timeline/get-sequence-context-menu-items.js +2 -0
  67. package/dist/components/Timeline/keyframe-clipboard.d.ts +5 -1
  68. package/dist/components/Timeline/keyframe-clipboard.js +3 -2
  69. package/dist/components/Timeline/save-sequence-prop.js +16 -7
  70. package/dist/components/Timeline/sequence-prop-clipboard.d.ts +31 -0
  71. package/dist/components/Timeline/sequence-prop-clipboard.js +142 -0
  72. package/dist/components/Timeline/split-selected-timeline-item.d.ts +0 -1
  73. package/dist/components/Timeline/split-selected-timeline-item.js +5 -13
  74. package/dist/components/Timeline/timeline-field-row-layout.js +2 -2
  75. package/dist/components/Timeline/timeline-field-utils.d.ts +1 -0
  76. package/dist/components/Timeline/timeline-field-utils.js +6 -1
  77. package/dist/components/Timeline/update-selected-easing.js +8 -0
  78. package/dist/components/Timeline/use-open-sequence-in-apps.js +3 -1
  79. package/dist/components/Timeline/use-resolved-stack-react-to-change.d.ts +1 -1
  80. package/dist/components/Timeline/use-resolved-stack-react-to-change.js +24 -3
  81. package/dist/components/Timeline/use-timeline-keyframe-drag.js +4 -4
  82. package/dist/components/UndoRedoButtons.js +5 -3
  83. package/dist/components/folder-menu-items.js +1 -0
  84. package/dist/components/get-open-in-menu-items.d.ts +4 -1
  85. package/dist/components/get-open-in-menu-items.js +99 -50
  86. package/dist/components/import-assets.js +7 -0
  87. package/dist/components/root-composition-menu-items.js +1 -0
  88. package/dist/components/selected-outline-control-layout.d.ts +14 -0
  89. package/dist/components/selected-outline-control-layout.js +94 -0
  90. package/dist/components/use-default-editor-info.js +28 -3
  91. package/dist/esm/{chunk-zpn4m49r.js → chunk-axbagh08.js} +6098 -5285
  92. package/dist/esm/{chunk-fgedsvhb.js → chunk-r46yxrjr.js} +1 -2
  93. package/dist/esm/internals.mjs +6097 -5284
  94. package/dist/esm/previewEntry.mjs +5989 -5176
  95. package/dist/esm/renderEntry.mjs +4 -2
  96. package/dist/helpers/get-canvas-capture-import.d.ts +7 -0
  97. package/dist/helpers/get-canvas-capture-import.js +43 -0
  98. package/dist/helpers/get-git-menu-item.d.ts +1 -1
  99. package/dist/helpers/get-git-menu-item.js +33 -3
  100. package/dist/helpers/inserted-element-selection.d.ts +12 -0
  101. package/dist/helpers/inserted-element-selection.js +29 -0
  102. package/dist/helpers/open-in-editor.d.ts +1 -0
  103. package/dist/helpers/open-in-editor.js +5 -1
  104. package/dist/helpers/pointer-session.d.ts +6 -2
  105. package/dist/helpers/pointer-session.js +29 -12
  106. package/dist/helpers/use-create-composition.d.ts +15 -2
  107. package/dist/helpers/use-create-composition.js +11 -17
  108. package/dist/helpers/use-menu-structure.js +1 -0
  109. package/dist/icons/git-client.d.ts +6 -0
  110. package/dist/icons/git-client.js +8 -0
  111. package/dist/icons/github.d.ts +4 -0
  112. package/dist/icons/github.js +11 -0
  113. package/dist/renderEntry.js +2 -2
  114. package/dist/state/modals.d.ts +9 -1
  115. package/dist/state/z-index.d.ts +0 -1
  116. package/dist/state/z-index.js +27 -33
  117. package/package.json +12 -12
@@ -21,6 +21,8 @@ const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info
21
21
  const imperative_state_1 = require("./imperative-state");
22
22
  const keyframe_clipboard_1 = require("./keyframe-clipboard");
23
23
  const save_effect_prop_1 = require("./save-effect-prop");
24
+ const save_sequence_prop_1 = require("./save-sequence-prop");
25
+ const sequence_prop_clipboard_1 = require("./sequence-prop-clipboard");
24
26
  const TimelineSelection_1 = require("./TimelineSelection");
25
27
  const update_selected_easing_1 = require("./update-selected-easing");
26
28
  const makeClipboardText = (payload) => JSON.stringify(payload);
@@ -76,37 +78,6 @@ const getPasteEffectsTarget = (selectedItems) => {
76
78
  };
77
79
  };
78
80
  exports.getPasteEffectsTarget = getPasteEffectsTarget;
79
- const isClipboardInterpolationFunction = (value) => {
80
- return (0, studio_shared_1.isKeyframeInterpolationFunction)(value);
81
- };
82
- const effectPropStatusToClipboardParam = (prop) => {
83
- if (prop.status === 'computed') {
84
- return null;
85
- }
86
- if (prop.status === 'static') {
87
- if (prop.codeValue === undefined) {
88
- return null;
89
- }
90
- return {
91
- type: 'static',
92
- value: prop.codeValue,
93
- };
94
- }
95
- if (!isClipboardInterpolationFunction(prop.interpolationFunction)) {
96
- return null;
97
- }
98
- return {
99
- type: 'keyframed',
100
- interpolationFunction: prop.interpolationFunction,
101
- keyframes: prop.keyframes,
102
- easing: prop.easing,
103
- clamping: prop.clamping,
104
- ...(prop.output === undefined || prop.output === 'linear'
105
- ? {}
106
- : { output: prop.output }),
107
- ...(prop.posterize === undefined ? {} : { posterize: prop.posterize }),
108
- };
109
- };
110
81
  const effectStatusToSnapshot = (effect) => {
111
82
  if (effect.importPath === null) {
112
83
  return null;
@@ -116,7 +87,7 @@ const effectStatusToSnapshot = (effect) => {
116
87
  if (prop.status === 'static' && prop.codeValue === undefined) {
117
88
  continue;
118
89
  }
119
- const param = effectPropStatusToClipboardParam(prop);
90
+ const param = (0, sequence_prop_clipboard_1.propStatusToClipboardParam)(prop);
120
91
  if (param === null) {
121
92
  return null;
122
93
  }
@@ -251,7 +222,7 @@ const getEffectPropClipboardDataFromSelection = ({ selection, propStatuses, }) =
251
222
  if (!prop) {
252
223
  return null;
253
224
  }
254
- const param = effectPropStatusToClipboardParam(prop);
225
+ const param = (0, sequence_prop_clipboard_1.propStatusToClipboardParam)(prop);
255
226
  if (param === null) {
256
227
  return null;
257
228
  }
@@ -397,7 +368,7 @@ const TimelineClipboardKeybindings = () => {
397
368
  event: 'keydown',
398
369
  key: 'c',
399
370
  callback: (e) => {
400
- var _a;
371
+ var _a, _b;
401
372
  const { selectedItems } = currentSelection.current;
402
373
  const propStatuses = propStatusesRef.current;
403
374
  const sequences = sequencesRef.current;
@@ -456,10 +427,37 @@ const TimelineClipboardKeybindings = () => {
456
427
  });
457
428
  return;
458
429
  }
430
+ if (selectedItems.some((selection) => selection.type === 'sequence-prop')) {
431
+ e.preventDefault();
432
+ if (selectedItems.length !== 1 ||
433
+ ((_a = selectedItems[0]) === null || _a === void 0 ? void 0 : _a.type) !== 'sequence-prop') {
434
+ (0, NotificationCenter_1.showNotification)('Select one property to copy its value', 3000);
435
+ return;
436
+ }
437
+ const payload = (0, sequence_prop_clipboard_1.getSequencePropClipboardDataFromSelection)({
438
+ selection: selectedItems[0],
439
+ propStatuses,
440
+ sequences,
441
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
442
+ });
443
+ if (payload === null) {
444
+ (0, NotificationCenter_1.showNotification)('Cannot copy property because its value cannot be copied', 3000);
445
+ return;
446
+ }
447
+ navigator.clipboard
448
+ .writeText(makeClipboardText(payload))
449
+ .then(() => {
450
+ (0, NotificationCenter_1.showNotification)('Copied property value', 1000);
451
+ })
452
+ .catch((err) => {
453
+ (0, NotificationCenter_1.showNotification)(`Could not copy property: ${err.message}`, 2000);
454
+ });
455
+ return;
456
+ }
459
457
  if (selectedItems.some((selection) => selection.type === 'sequence-effect-prop')) {
460
458
  e.preventDefault();
461
459
  if (selectedItems.length !== 1 ||
462
- ((_a = selectedItems[0]) === null || _a === void 0 ? void 0 : _a.type) !== 'sequence-effect-prop') {
460
+ ((_b = selectedItems[0]) === null || _b === void 0 ? void 0 : _b.type) !== 'sequence-effect-prop') {
463
461
  (0, NotificationCenter_1.showNotification)('Select one effect prop to copy its value', 3000);
464
462
  return;
465
463
  }
@@ -732,6 +730,72 @@ const TimelineClipboardKeybindings = () => {
732
730
  (0, NotificationCenter_1.showNotification)(`Could not paste easing: ${err.message}`, 3000);
733
731
  });
734
732
  }
733
+ const sequencePropResult = (0, studio_shared_1.parseSequencePropClipboardDataResult)(text);
734
+ if (sequencePropResult.status !== 'invalid') {
735
+ e.preventDefault();
736
+ if (sequencePropResult.status === 'unsupported-version') {
737
+ (0, NotificationCenter_1.showNotification)('Cannot paste property copied from a different Remotion Studio version', 4000);
738
+ return;
739
+ }
740
+ const sequencePropTarget = (0, sequence_prop_clipboard_1.getPasteSequencePropTarget)({
741
+ selectedItems,
742
+ payload: sequencePropResult.data,
743
+ propStatuses,
744
+ sequences,
745
+ overrideIdsToNodePaths: overrideIdToNodePathMappings,
746
+ });
747
+ if (sequencePropTarget.type !== 'valid') {
748
+ switch (sequencePropTarget.type) {
749
+ case 'none':
750
+ (0, NotificationCenter_1.showNotification)('Select a property or sequence to paste onto', 3000);
751
+ return;
752
+ case 'prop-mismatch':
753
+ (0, NotificationCenter_1.showNotification)('Select the same property to paste this value', 3000);
754
+ return;
755
+ case 'uncopyable':
756
+ (0, NotificationCenter_1.showNotification)('Cannot paste onto a property that cannot be updated', 3000);
757
+ return;
758
+ case 'incompatible':
759
+ (0, NotificationCenter_1.showNotification)('The copied value is not compatible with this property', 3000);
760
+ return;
761
+ default:
762
+ throw new Error(`Unexpected paste target: ${sequencePropTarget}`);
763
+ }
764
+ }
765
+ const { param } = sequencePropResult.data;
766
+ return (0, save_sequence_prop_1.saveSequenceProps)({
767
+ changes: sequencePropTarget.targets.map((pasteTarget) => ({
768
+ fileName: pasteTarget.fileName,
769
+ nodePath: pasteTarget.nodePath,
770
+ fieldKey: pasteTarget.fieldKey,
771
+ value: param.type === 'static' ? param.value : undefined,
772
+ defaultValue: pasteTarget.defaultValue,
773
+ schema: pasteTarget.schema,
774
+ ...(param.type === 'keyframed'
775
+ ? {
776
+ sourceEdit: {
777
+ type: 'clipboard-param',
778
+ param,
779
+ },
780
+ }
781
+ : {}),
782
+ })),
783
+ addedKeyframes: null,
784
+ movedKeyframes: null,
785
+ setPropStatuses,
786
+ clientId,
787
+ undoLabel: sequencePropTarget.targets.length > 1
788
+ ? 'Paste property onto selected sequences'
789
+ : 'Paste property',
790
+ redoLabel: sequencePropTarget.targets.length > 1
791
+ ? 'Reapply property paste onto selected sequences'
792
+ : 'Reapply property paste',
793
+ }).then(() => {
794
+ (0, NotificationCenter_1.showNotification)(sequencePropTarget.targets.length > 1
795
+ ? 'Pasted property onto selected sequences'
796
+ : 'Pasted property', 2000);
797
+ });
798
+ }
735
799
  const effectPropResult = (0, studio_shared_1.parseEffectPropClipboardDataResult)(text);
736
800
  if (effectPropResult.status !== 'invalid') {
737
801
  e.preventDefault();
@@ -42,16 +42,11 @@ const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragV
42
42
  }
43
43
  onDragEnd();
44
44
  }, [onSave, onDragEnd, propStatus]);
45
- const swatchStyle = (0, react_1.useMemo)(() => {
46
- return {
47
- marginLeft: 5,
48
- };
49
- }, []);
50
45
  if (currentValue === 'none') {
51
46
  return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
52
47
  jsx_runtime_1.jsx("span", { style: noneLabelStyle, children: "None" }), jsx_runtime_1.jsx("button", { type: "button", style: setButtonStyle, title: `Set ${(_b = field.description) !== null && _b !== void 0 ? _b : field.key} to gray`, onClick: () => onChangeComplete(DEFAULT_SET_COLOR), children: "Set" })
53
48
  ] }));
54
49
  }
55
- return (jsx_runtime_1.jsx("span", { style: containerStyle, children: jsx_runtime_1.jsx(ColorPicker_1.ColorPicker, { value: currentValue, status: "ok", onChange: onChange, onChangeComplete: onChangeComplete, width: SWATCH_WIDTH, height: SWATCH_HEIGHT, disabled: false, name: field.key, title: currentValue, style: swatchStyle }) }));
50
+ return (jsx_runtime_1.jsx("span", { style: containerStyle, children: jsx_runtime_1.jsx(ColorPicker_1.ColorPicker, { value: currentValue, status: "ok", onChange: onChange, onChangeComplete: onChangeComplete, width: SWATCH_WIDTH, height: SWATCH_HEIGHT, disabled: false, name: field.key, title: currentValue }) }));
56
51
  };
57
52
  exports.TimelineColorField = TimelineColorField;
@@ -274,9 +274,9 @@ const TimelineDragHandlerInner = () => {
274
274
  if (!dragging.dragging) {
275
275
  return;
276
276
  }
277
- return (0, pointer_session_1.startPointerSession)({
277
+ return (0, pointer_session_1.startCapturedPointerSession)({
278
278
  event: dragging,
279
- target: dragging.target,
279
+ captureTarget: dragging.target,
280
280
  onMove: onPointerMoveScrubbing,
281
281
  onEnd: (reason, endEvent) => {
282
282
  if ((reason === 'pointerup' || reason === 'buttons-released') &&
@@ -321,7 +321,7 @@ const TimelineEffectItem = ({ label, nodePathInfo, effectIndex, effectSchema, do
321
321
  ...(dropIndicator === 'before' ? { top: -1 } : { bottom: -1 }),
322
322
  };
323
323
  }, [dropIndicator]);
324
- const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: containsSelection, outerHeight: null, children: jsx_runtime_1.jsx("span", { title: label, style: labelStyle, children: label }) }));
324
+ const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), style: rowStyle, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: containsSelection, isFieldRow: false, outerHeight: null, children: jsx_runtime_1.jsx("span", { title: label, style: labelStyle, children: label }) }));
325
325
  const draggableRow = canReorder ? (jsx_runtime_1.jsxs("div", { draggable: true, onDragStart: onDragStart, onDragEnd: onDragEnd, onDragOver: onDragOver, onDragLeave: onDragLeave, onDrop: onDrop, style: reorderWrapper, children: [reorderLineStyle ? jsx_runtime_1.jsx("div", { style: reorderLineStyle }) : null, row] })) : (row);
326
326
  return previewConnected ? (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: draggableRow })) : (draggableRow);
327
327
  };
@@ -63,11 +63,18 @@ const TimelineEffectPropValue = ({ field, nodePath, validatedLocation, sourceFra
63
63
  status: propStatus,
64
64
  frame: sourceFrame,
65
65
  value,
66
+ defaultEasing: (0, studio_shared_1.isSchemaFieldHoldOnly)({
67
+ schema: field.effectSchema,
68
+ key: field.key,
69
+ })
70
+ ? { type: 'step1' }
71
+ : undefined,
66
72
  })
67
73
  : remotion_1.Internals.makeStaticDragOverride(value);
68
74
  setEffectDragOverrides(nodePath, field.effectIndex, field.key, nextDragOverrideValue);
69
75
  }, [
70
76
  field.effectIndex,
77
+ field.effectSchema,
71
78
  field.key,
72
79
  nodePath,
73
80
  propStatus,
@@ -326,7 +333,7 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
326
333
  property: field.key,
327
334
  }).catch(() => undefined);
328
335
  }, [field.key, previewServerState.type, validatedLocation]);
329
- const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, children: jsx_runtime_1.jsx(TimelineEffectPropValueAtCurrentFrame, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, keyframeDisplayOffset: keyframeDisplayOffset }) }) }));
336
+ const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, isFieldRow: true, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, keyframeControls: keyframeControls, children: jsx_runtime_1.jsx(TimelineEffectPropValueAtCurrentFrame, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, keyframeDisplayOffset: keyframeDisplayOffset }) }) }));
330
337
  return jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: row });
331
338
  };
332
339
  exports.TimelineEffectPropItem = TimelineEffectPropItem;
@@ -4,9 +4,6 @@ exports.TimelineEnumField = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const ComboBox_1 = require("../NewComposition/ComboBox");
7
- const comboboxStyle = {
8
- marginLeft: 8,
9
- };
10
7
  const TimelineEnumField = ({ field, propStatus, effectiveValue, onSave, onDragValueChange, onDragEnd, }) => {
11
8
  const { fieldSchema } = field;
12
9
  if (fieldSchema.type !== 'enum') {
@@ -37,6 +34,6 @@ const TimelineEnumField = ({ field, propStatus, effectiveValue, onSave, onDragVa
37
34
  disabled: false,
38
35
  }));
39
36
  }, [variantKeys, onSelect]);
40
- return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "small", title: field.key, selectedId: current, values: items, style: comboboxStyle }));
37
+ return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "small", title: field.key, selectedId: current, values: items }));
41
38
  };
42
39
  exports.TimelineEnumField = TimelineEnumField;
@@ -45,7 +45,7 @@ const TimelineExpandedRowInner = ({ node, depth, nestedDepth, rowDepthBase, getI
45
45
  const isExpanded = getIsExpanded(node.nodePathInfo);
46
46
  return (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(node.nodePathInfo), label: `${node.label} section`, disabled: false }), style: {
47
47
  height: timeline_layout_1.TREE_GROUP_ROW_HEIGHT,
48
- }, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx("span", { style: labelStyle, children: node.label }) }));
48
+ }, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, isFieldRow: false, outerHeight: null, children: jsx_runtime_1.jsx("span", { style: labelStyle, children: node.label }) }));
49
49
  }
50
50
  if (node.field) {
51
51
  if (node.field.kind === 'effect-field') {
@@ -58,6 +58,6 @@ const TimelineExpandedRowInner = ({ node, depth, nestedDepth, rowDepthBase, getI
58
58
  }
59
59
  return (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: {
60
60
  height: (0, timeline_layout_1.getTreeRowHeight)(node),
61
- }, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx("span", { style: labelStyle, children: node.label }) }));
61
+ }, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, showSelectedBackground: true, containsSelection: false, isFieldRow: false, outerHeight: null, children: jsx_runtime_1.jsx("span", { style: labelStyle, children: node.label }) }));
62
62
  };
63
63
  exports.TimelineExpandedRow = react_1.default.memo(TimelineExpandedRowInner);
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
- import type { SchemaFieldInfo } from '../../helpers/timeline-layout';
2
+ import { type SchemaFieldInfo } from '../../helpers/timeline-layout';
3
3
  export declare const TimelineFieldRowContent: React.FC<{
4
4
  readonly field: SchemaFieldInfo;
5
5
  readonly rowDepth: number;
6
6
  readonly selected: boolean;
7
+ readonly keyframeControls: React.ReactNode;
7
8
  readonly children: React.ReactNode;
8
9
  }>;
@@ -3,21 +3,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineFieldRowContent = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
+ const timeline_layout_1 = require("../../helpers/timeline-layout");
6
7
  const timeline_field_row_layout_1 = require("./timeline-field-row-layout");
7
8
  const TimelineFieldLabel_1 = require("./TimelineFieldLabel");
9
+ const TimelineRowChrome_1 = require("./TimelineRowChrome");
10
+ const TimelineRowLayoutContext_1 = require("./TimelineRowLayoutContext");
8
11
  const Transform3DModeContext_1 = require("./Transform3DModeContext");
9
- const TimelineFieldRowContent = ({ field, rowDepth, selected, children }) => {
12
+ const stackedHeaderStyle = {
13
+ display: 'flex',
14
+ flex: `0 0 ${timeline_layout_1.SCHEMA_FIELD_ROW_HEIGHT}px`,
15
+ minWidth: 0,
16
+ };
17
+ const stackedLabelStyle = {
18
+ flex: 1,
19
+ minWidth: 0,
20
+ };
21
+ const TimelineFieldRowContent = ({ field, rowDepth, selected, keyframeControls, children }) => {
10
22
  var _a;
11
23
  const transform3DMode = (0, react_1.useContext)(Transform3DModeContext_1.Transform3DModeContext);
24
+ const { keyframeControlsPlacement } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
12
25
  const stacked = (0, timeline_field_row_layout_1.isTimelineFieldStacked)({ field, transform3DMode });
13
26
  const compactStacked = stacked && field.typeName !== 'text-content';
14
27
  const label = (jsx_runtime_1.jsx(TimelineFieldLabel_1.TimelineFieldLabel, { rowDepth: rowDepth, selected: selected, label: (_a = field.description) !== null && _a !== void 0 ? _a : field.key, stacked: stacked }));
15
28
  const value = (jsx_runtime_1.jsx("div", { style: compactStacked
16
29
  ? timeline_field_row_layout_1.timelineCompactStackedFieldValueColumnStyle
17
30
  : timeline_field_row_layout_1.timelineFieldValueColumnStyle, children: children }));
31
+ const controls = keyframeControlsPlacement === 'after-label' ? (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowKeyframeControlsColumn, { depth: rowDepth, children: keyframeControls })) : null;
18
32
  if (stacked) {
19
- return (jsx_runtime_1.jsxs("div", { style: timeline_field_row_layout_1.timelineStackedFieldContentStyle, children: [label, value] }));
33
+ return (jsx_runtime_1.jsxs("div", { style: timeline_field_row_layout_1.timelineStackedFieldContentStyle, children: [controls ? (jsx_runtime_1.jsxs("div", { style: stackedHeaderStyle, children: [
34
+ jsx_runtime_1.jsx("div", { style: stackedLabelStyle, children: label }), controls] })) : (label), value] }));
20
35
  }
21
- return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [label, value] }));
36
+ return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [label, controls, value] }));
22
37
  };
23
38
  exports.TimelineFieldRowContent = TimelineFieldRowContent;
@@ -60,7 +60,6 @@ const systemFonts = [
60
60
  value: fontFamily,
61
61
  }));
62
62
  const triggerStyle = {
63
- marginLeft: 8,
64
63
  padding: '3px 4px',
65
64
  display: 'inline-flex',
66
65
  alignItems: 'center',
@@ -508,7 +507,7 @@ const TimelineFontFamilyField = ({ field, propStatus, effectiveValue, onSave, on
508
507
  jsx_runtime_1.jsx("div", { title: selected.label, style: { ...triggerLabel, ...selectedPreviewStyle }, children: selected.label }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(caret_1.CaretDown, { small: true })
509
508
  ] }), saveError === null ? null : jsx_runtime_1.jsx("div", { style: errorText, children: saveError }), opened && size
510
509
  ? react_dom_1.default.createPortal(jsx_runtime_1.jsx("div", { style: styles_1.fullScreenOverlay, onPointerDown: (event) => event.stopPropagation(), children: jsx_runtime_1.jsx("div", { style: styles_1.outerPortal, className: "css-reset", children: jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onOutsideClick: hide, onEscape: hide, children: jsx_runtime_1.jsxs("div", { style: portalStyle({ size }), children: [
511
- jsx_runtime_1.jsx("div", { style: { padding: 6 }, children: jsx_runtime_1.jsx("input", { ref: inputRef, value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: onKeyDown, placeholder: "Search fonts", style: searchInput }) }), filteredOptions.length === 0 ? (jsx_runtime_1.jsx("div", { style: noResults, children: "No fonts found" })) : (jsx_runtime_1.jsxs("div", { ref: listRef, style: listStyle, onScroll: (event) => {
510
+ jsx_runtime_1.jsx("div", { style: { padding: 6 }, children: jsx_runtime_1.jsx("input", { ref: inputRef, value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: onKeyDown, placeholder: "Search fonts", style: searchInput }) }), filteredOptions.length === 0 ? (jsx_runtime_1.jsx("div", { style: noResults, children: "No fonts found" })) : (jsx_runtime_1.jsxs("div", { ref: listRef, style: listStyle, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, onScroll: (event) => {
512
511
  setScrollTop(event.currentTarget.scrollTop);
513
512
  }, children: [
514
513
  jsx_runtime_1.jsx("div", { style: { height: visibleRange.start * ROW_HEIGHT } }), renderedOptions.map((option, index) => {
@@ -275,9 +275,9 @@ const TimelineInOutDragHandlerInner = () => {
275
275
  if (inOutDragging.dragging === false) {
276
276
  return;
277
277
  }
278
- return (0, pointer_session_1.startPointerSession)({
278
+ return (0, pointer_session_1.startCapturedPointerSession)({
279
279
  event: inOutDragging,
280
- target: inOutDragging.target,
280
+ captureTarget: inOutDragging.target,
281
281
  onMove: onPointerMoveInOut,
282
282
  onEnd: (reason, endEvent) => {
283
283
  if ((reason === 'pointerup' || reason === 'buttons-released') &&
@@ -43,6 +43,7 @@ const colors_1 = require("../../helpers/colors");
43
43
  const get_left_of_timeline_slider_1 = require("../../helpers/get-left-of-timeline-slider");
44
44
  const timeline_layout_1 = require("../../helpers/timeline-layout");
45
45
  const ContextMenu_1 = require("../ContextMenu");
46
+ const EasingEditorModal_1 = require("./EasingEditorModal");
46
47
  const TimelineSelection_1 = require("./TimelineSelection");
47
48
  const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
48
49
  const update_selected_easing_1 = require("./update-selected-easing");
@@ -138,7 +139,7 @@ const TimelineKeyframeEasingLineInteraction = ({ fromFrame, toFrame, nodePathInf
138
139
  id: 'linear',
139
140
  keyHint: null,
140
141
  label: 'Linear',
141
- leftItem: null,
142
+ leftItem: (jsx_runtime_1.jsx(EasingEditorModal_1.EasingPresetPreview, { color: colors_1.LIGHT_TEXT, easing: studio_shared_1.LINEAR_KEYFRAME_EASING, height: 18, nonScalingStroke: true, strokeWidth: 5, width: 18 })),
142
143
  disabled: previewServerState.type !== 'connected',
143
144
  onClick: () => updateEasing(studio_shared_1.LINEAR_KEYFRAME_EASING),
144
145
  quickSwitcherLabel: null,
@@ -150,7 +151,7 @@ const TimelineKeyframeEasingLineInteraction = ({ fromFrame, toFrame, nodePathInf
150
151
  id: preset.id,
151
152
  keyHint: null,
152
153
  label: preset.label,
153
- leftItem: null,
154
+ leftItem: (jsx_runtime_1.jsx(EasingEditorModal_1.EasingPresetPreview, { color: colors_1.LIGHT_TEXT, easing: preset.easing, height: 18, nonScalingStroke: true, strokeWidth: 5, width: 18 })),
154
155
  disabled: previewServerState.type !== 'connected',
155
156
  onClick: () => updateEasing(preset.easing),
156
157
  quickSwitcherLabel: null,
@@ -58,9 +58,9 @@ const TimelineLayerEye = ({ onInvoked, hidden, type }) => {
58
58
  layerPointedDown = hidden ? 'enable' : 'disable';
59
59
  onInvoked(layerPointedDown);
60
60
  lastPaintedLayerEye = e.currentTarget;
61
- stopLayerPointerSession = (0, pointer_session_1.startPointerSession)({
61
+ stopLayerPointerSession = (0, pointer_session_1.startCapturedPointerSession)({
62
62
  event: e,
63
- target: e.currentTarget,
63
+ captureTarget: e.currentTarget,
64
64
  onMove: (moveEvent) => {
65
65
  var _a, _b;
66
66
  const pointedElement = (_a = document
@@ -36,16 +36,18 @@ const TimelineNumberField = ({ field, effectiveValue, onSave, onDragValueChange,
36
36
  }, [onSave, propStatus]);
37
37
  const configuredStep = field.fieldSchema.type === 'number' ? field.fieldSchema.step : undefined;
38
38
  const step = configuredStep !== null && configuredStep !== void 0 ? configuredStep : 1;
39
+ const allowStepMismatch = field.group === 'crop' ||
40
+ ('kind' in field && field.kind === 'effect-field');
39
41
  const formatter = (0, react_1.useCallback)((v) => {
40
42
  return (0, timeline_field_display_utils_1.formatTimelineFieldValueForDisplay)({
41
43
  fieldSchema: field.fieldSchema,
42
44
  value: v,
43
45
  });
44
46
  }, [field.fieldSchema]);
45
- return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : effectiveValue, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: field.fieldSchema.type === 'number'
47
+ return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : effectiveValue, buttonStyle: timeline_field_utils_1.leftAlignedDraggerStyle, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: field.fieldSchema.type === 'number'
46
48
  ? ((_a = field.fieldSchema.min) !== null && _a !== void 0 ? _a : -Infinity)
47
49
  : -Infinity, max: field.fieldSchema.type === 'number'
48
50
  ? ((_b = field.fieldSchema.max) !== null && _b !== void 0 ? _b : Infinity)
49
- : Infinity, step: step, formatter: formatter, rightAlign: false }));
51
+ : Infinity, step: step, formatter: formatter, rightAlign: false, allowStepMismatch: allowStepMismatch }));
50
52
  };
51
53
  exports.TimelineNumberField = TimelineNumberField;
@@ -52,7 +52,7 @@ const TimelineRotationField = ({ field, effectiveValue, propStatus, onSave, onDr
52
52
  step: configuredStep,
53
53
  }), [configuredStep]);
54
54
  const serializeValue = (0, react_1.useCallback)((value) => isCssRotation
55
- ? (0, timeline_rotation_utils_1.serializeCssRotation)(value, decimalPlaces)
55
+ ? (0, timeline_rotation_utils_1.serializeCssRotation)(value, Math.max(6, decimalPlaces))
56
56
  : (0, timeline_field_utils_1.normalizeTimelineNumber)(value), [decimalPlaces, isCssRotation]);
57
57
  const serializeRotation = (0, react_1.useCallback)((rotation) => (0, timeline_rotation_utils_1.serializeCssRotationFromEuler)({
58
58
  rotation,
@@ -141,9 +141,9 @@ const TimelineRotationField = ({ field, effectiveValue, propStatus, onSave, onDr
141
141
  propStatus.codeValue,
142
142
  serializeRotation,
143
143
  ]);
144
- const angleDragger = (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : degrees, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false, "aria-label": isCssRotation ? 'Rotation Z' : 'Rotation angle' }));
144
+ const angleDragger = (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : degrees, buttonStyle: timeline_field_utils_1.leftAlignedDraggerStyle, style: timeline_field_utils_1.draggerStyle, status: "ok", small: true, onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: min, max: max, step: step, formatter: formatter, rightAlign: false, allowStepMismatch: true, "aria-label": isCssRotation ? 'Rotation Z' : 'Rotation angle' }));
145
145
  if (show3D) {
146
- return (jsx_runtime_1.jsx("span", { style: containerStyle, children: ROTATION_LABELS.map((rotationLabel, rotationIndex) => (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (dragRotation !== null && dragRotation !== void 0 ? dragRotation : cssRotation)[rotationIndex], buttonStyle: compactDraggerStyle, status: "ok", small: true, onValueChange: (newValue) => onRotationValueChange(rotationIndex, newValue), onValueChangeEnd: (newValue) => onRotationValueChangeEnd(rotationIndex, newValue), onTextChange: (newValue) => onRotationTextChange(rotationIndex, newValue), min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, "aria-label": `Rotation ${rotationLabel}` }, rotationLabel))) }));
146
+ return (jsx_runtime_1.jsx("span", { style: containerStyle, children: ROTATION_LABELS.map((rotationLabel, rotationIndex) => (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: (dragRotation !== null && dragRotation !== void 0 ? dragRotation : cssRotation)[rotationIndex], buttonStyle: compactDraggerStyle, status: "ok", small: true, onValueChange: (newValue) => onRotationValueChange(rotationIndex, newValue), onValueChangeEnd: (newValue) => onRotationValueChangeEnd(rotationIndex, newValue), onTextChange: (newValue) => onRotationTextChange(rotationIndex, newValue), min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false, allowStepMismatch: true, "aria-label": `Rotation ${rotationLabel}` }, rotationLabel))) }));
147
147
  }
148
148
  return angleDragger;
149
149
  };
@@ -1,6 +1,10 @@
1
1
  import React from 'react';
2
2
  import type { TimelineSelectionInteraction } from './TimelineSelection';
3
3
  import { type TimelineSelection } from './TimelineSelection';
4
+ export declare const TimelineRowKeyframeControlsColumn: React.FC<{
5
+ readonly children: React.ReactNode;
6
+ readonly depth: number;
7
+ }>;
4
8
  export declare const TimelineRowChrome: React.FC<{
5
9
  readonly depth: number;
6
10
  readonly eye: React.ReactNode;
@@ -15,6 +19,7 @@ export declare const TimelineRowChrome: React.FC<{
15
19
  readonly showSelectedBackground: boolean;
16
20
  readonly containsSelection: boolean;
17
21
  readonly hovered?: boolean;
22
+ readonly isFieldRow: boolean;
18
23
  readonly outerHeight: number | null;
19
24
  readonly onDragLeave?: (e: React.DragEvent<HTMLDivElement>) => void;
20
25
  readonly onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimelineRowChrome = void 0;
3
+ exports.TimelineRowChrome = exports.TimelineRowKeyframeControlsColumn = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../../helpers/colors");
@@ -24,17 +24,22 @@ const keyframeControlsColumnBaseStyle = {
24
24
  flexShrink: 0,
25
25
  justifyContent: 'flex-start',
26
26
  };
27
- const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, style, selected, selectable, selectionItem, onSelect, showSelectedBackground, containsSelection, hovered = false, outerHeight, onDragLeave, onDragOver, onDrop, onDoubleClick, onPointerEnter, onPointerLeave, }) => {
28
- const ref = (0, react_1.useRef)(null);
29
- const { basePadding, keyframeControlsPadding, rowBorderRadius, rowHorizontalMargin, } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
30
- const indentWidth = (0, timeline_row_layout_1.getTimelineRowIndentWidth)(depth);
31
- (0, TimelineSelection_1.useTimelineFocusableItem)(selectionItem, ref);
32
- const keyframeControlsColumnStyle = (0, react_1.useMemo)(() => ({
27
+ const TimelineRowKeyframeControlsColumn = ({ children, depth }) => {
28
+ const { basePadding, keyframeControlsPadding } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
29
+ const style = (0, react_1.useMemo)(() => ({
33
30
  ...keyframeControlsColumnBaseStyle,
34
31
  boxSizing: keyframeControlsPadding === 0 ? undefined : 'border-box',
35
32
  paddingLeft: keyframeControlsPadding,
36
33
  width: (0, timeline_row_layout_1.getTimelineRowLeftChromeWidth)(depth, basePadding),
37
34
  }), [basePadding, depth, keyframeControlsPadding]);
35
+ return (jsx_runtime_1.jsx("div", { style: leftChromeStyle, children: jsx_runtime_1.jsx("div", { style: style, children: children }) }));
36
+ };
37
+ exports.TimelineRowKeyframeControlsColumn = TimelineRowKeyframeControlsColumn;
38
+ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, style, selected, selectable, selectionItem, onSelect, showSelectedBackground, containsSelection, hovered = false, isFieldRow, outerHeight, onDragLeave, onDragOver, onDrop, onDoubleClick, onPointerEnter, onPointerLeave, }) => {
39
+ const ref = (0, react_1.useRef)(null);
40
+ const { basePadding, keyframeControlsPlacement, rowBorderRadius, rowHorizontalMargin, } = (0, react_1.useContext)(TimelineRowLayoutContext_1.TimelineRowLayoutContext);
41
+ const indentWidth = (0, timeline_row_layout_1.getTimelineRowIndentWidth)(depth);
42
+ (0, TimelineSelection_1.useTimelineFocusableItem)(selectionItem, ref);
38
43
  const chromeColumnStyle = (0, react_1.useMemo)(() => ({
39
44
  alignItems: 'center',
40
45
  alignSelf: 'stretch',
@@ -87,8 +92,8 @@ const TimelineRowChrome = ({ depth, eye, keyframeControls, arrow, children, styl
87
92
  backgroundColor: highlightBackground,
88
93
  };
89
94
  }, [outerHeight, highlightBackground]);
90
- const chrome = (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
91
- jsx_runtime_1.jsx("div", { style: leftChromeStyle, children: keyframeControls ? (jsx_runtime_1.jsx("div", { style: keyframeControlsColumnStyle, children: keyframeControls })) : (jsx_runtime_1.jsxs("div", { style: chromeColumnStyle, children: [eye, indentWidth > 0 ? jsx_runtime_1.jsx(Padder_1.Padder, { depth: depth }) : null, arrow] })) }), children] }));
95
+ const shouldRenderLeftChrome = !isFieldRow || keyframeControlsPlacement === 'before-label';
96
+ const chrome = (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [shouldRenderLeftChrome ? (keyframeControls ? (jsx_runtime_1.jsx(exports.TimelineRowKeyframeControlsColumn, { depth: depth, children: keyframeControls })) : (jsx_runtime_1.jsx("div", { style: leftChromeStyle, children: jsx_runtime_1.jsxs("div", { style: chromeColumnStyle, children: [eye, indentWidth > 0 ? jsx_runtime_1.jsx(Padder_1.Padder, { depth: depth }) : null, arrow] }) }))) : null, children] }));
92
97
  if (outerStyle) {
93
98
  return (jsx_runtime_1.jsx("div", { ref: ref, style: outerStyle, onDragLeave: onDragLeave, onDragOver: onDragOver, onDrop: onDrop, onPointerDown: selectable ? onPointerDown : undefined, onContextMenu: selectable ? onContextMenu : undefined, onDoubleClick: onDoubleClick, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsx("div", { style: innerRowStyle, children: chrome }) }));
94
99
  }
@@ -2,6 +2,7 @@ type TimelineRowLayout = {
2
2
  readonly basePadding: number;
3
3
  readonly highlightSelectedLabel: boolean;
4
4
  readonly keyframeControlsPadding: number;
5
+ readonly keyframeControlsPlacement: 'before-label' | 'after-label';
5
6
  readonly rowBorderRadius: number;
6
7
  readonly rowHorizontalMargin: number;
7
8
  };
@@ -2,18 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TimelineRowLayoutContext = exports.INSPECTOR_TIMELINE_ROW_LAYOUT = void 0;
4
4
  const react_1 = require("react");
5
+ const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
5
6
  const timeline_row_layout_1 = require("./timeline-row-layout");
6
7
  exports.INSPECTOR_TIMELINE_ROW_LAYOUT = {
7
8
  basePadding: timeline_row_layout_1.INSPECTOR_ROW_BASE_PADDING,
8
9
  highlightSelectedLabel: false,
9
10
  keyframeControlsPadding: 0,
11
+ keyframeControlsPlacement: 'after-label',
10
12
  rowBorderRadius: 4,
11
- rowHorizontalMargin: 4,
13
+ rowHorizontalMargin: InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING,
12
14
  };
13
15
  exports.TimelineRowLayoutContext = (0, react_1.createContext)({
14
16
  basePadding: timeline_row_layout_1.TIMELINE_ROW_BASE_PADDING,
15
17
  highlightSelectedLabel: true,
16
18
  keyframeControlsPadding: timeline_row_layout_1.TIMELINE_ROW_BASE_PADDING,
19
+ keyframeControlsPlacement: 'before-label',
17
20
  rowBorderRadius: 0,
18
21
  rowHorizontalMargin: 0,
19
22
  });
@@ -15,11 +15,15 @@ const leftDraggerStyle = {
15
15
  paddingBottom: 2,
16
16
  paddingLeft: 0,
17
17
  paddingTop: 2,
18
+ textAlign: 'left',
19
+ width: 52,
18
20
  };
19
21
  const rightDraggerStyle = {
20
22
  paddingBottom: 2,
21
23
  paddingRight: 0,
22
24
  paddingTop: 2,
25
+ textAlign: 'left',
26
+ width: 52,
23
27
  };
24
28
  const containerStyle = {
25
29
  alignItems: 'center',
@@ -1013,9 +1013,9 @@ const useTimelineMarqueeSelection = () => {
1013
1013
  const onPointerMove = (moveEvent) => {
1014
1014
  updateSelection(moveEvent.clientX, moveEvent.clientY);
1015
1015
  };
1016
- (0, pointer_session_1.startPointerSession)({
1016
+ (0, pointer_session_1.startCapturedPointerSession)({
1017
1017
  event,
1018
- target,
1018
+ captureTarget: target,
1019
1019
  onMove: onPointerMove,
1020
1020
  onEnd: (reason, endEvent) => {
1021
1021
  if ((reason === 'pointerup' || reason === 'buttons-released') &&