@remotion/studio 4.0.486 → 4.0.487

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/ContextMenu.js +2 -1
  2. package/dist/components/CurrentComposition.js +43 -2
  3. package/dist/components/EditorContexts.js +2 -1
  4. package/dist/components/GlobalKeybindings.js +19 -0
  5. package/dist/components/InspectorSourceLocation.d.ts +1 -0
  6. package/dist/components/InspectorSourceLocation.js +18 -3
  7. package/dist/components/KeyboardShortcutsExplainer.js +4 -0
  8. package/dist/components/Preview.js +1 -1
  9. package/dist/components/PreviewToolbar.js +2 -1
  10. package/dist/components/RenderButton.js +1 -0
  11. package/dist/components/RenderModal/OptionExplainer.d.ts +11 -1
  12. package/dist/components/RenderModal/OptionExplainer.js +31 -11
  13. package/dist/components/RenderModal/OptionExplainerBubble.d.ts +15 -1
  14. package/dist/components/RenderModal/OptionExplainerBubble.js +17 -3
  15. package/dist/components/RenderModal/SchemaEditor/Fieldset.d.ts +1 -0
  16. package/dist/components/RenderModal/SchemaEditor/Fieldset.js +6 -1
  17. package/dist/components/RenderModal/SchemaEditor/SchemaEditor.js +1 -2
  18. package/dist/components/RenderModal/WebRenderModal.js +5 -2
  19. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +3 -0
  20. package/dist/components/RenderModal/WebRenderModalAdvanced.js +92 -5
  21. package/dist/components/RenderModal/WebRenderModalBasic.js +2 -2
  22. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +1 -0
  23. package/dist/components/RenderQueue/client-side-render-types.d.ts +2 -1
  24. package/dist/components/SelectedOutlineElement.d.ts +4 -0
  25. package/dist/components/SelectedOutlineElement.js +56 -11
  26. package/dist/components/SelectedOutlineOverlay.d.ts +2 -0
  27. package/dist/components/SelectedOutlineOverlay.js +53 -2
  28. package/dist/components/SelectedOutlineUvControls.js +13 -6
  29. package/dist/components/SnappingProvider.d.ts +4 -0
  30. package/dist/components/SnappingProvider.js +24 -0
  31. package/dist/components/SnappingToggle.d.ts +2 -0
  32. package/dist/components/SnappingToggle.js +26 -0
  33. package/dist/components/Splitter/SplitterContext.d.ts +1 -1
  34. package/dist/components/Timeline/TimelineSelection.js +5 -0
  35. package/dist/components/VisualControls/ClickableFileName.js +2 -2
  36. package/dist/components/VisualControls/VisualControlsContent.js +9 -1
  37. package/dist/components/effect-drag-and-drop.js +30 -9
  38. package/dist/components/import-assets.d.ts +1 -1
  39. package/dist/components/options-sidebar-tabs.d.ts +1 -0
  40. package/dist/components/options-sidebar-tabs.js +6 -1
  41. package/dist/components/selected-outline-snap.d.ts +36 -0
  42. package/dist/components/selected-outline-snap.js +158 -0
  43. package/dist/esm/{chunk-975rp13y.js → chunk-y2t24cx0.js} +4776 -3933
  44. package/dist/esm/internals.mjs +4776 -3933
  45. package/dist/esm/previewEntry.mjs +5095 -4252
  46. package/dist/esm/renderEntry.mjs +1 -1
  47. package/dist/helpers/retry-payload.js +1 -0
  48. package/dist/helpers/use-menu-structure.js +43 -2
  49. package/dist/icons/magnet.d.ts +3 -0
  50. package/dist/icons/magnet.js +8 -0
  51. package/dist/icons/react.d.ts +5 -0
  52. package/dist/icons/react.js +8 -0
  53. package/dist/state/editor-guides.d.ts +2 -2
  54. package/dist/state/editor-snapping.d.ts +8 -0
  55. package/dist/state/editor-snapping.js +18 -0
  56. package/dist/state/modals.d.ts +2 -1
  57. package/package.json +12 -12
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnappingToggle = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const no_react_1 = require("remotion/no-react");
7
+ const colors_1 = require("../helpers/colors");
8
+ const use_keybinding_1 = require("../helpers/use-keybinding");
9
+ const magnet_1 = require("../icons/magnet");
10
+ const editor_snapping_1 = require("../state/editor-snapping");
11
+ const ControlButton_1 = require("./ControlButton");
12
+ const SnappingToggle = () => {
13
+ const { editorSnapping, setEditorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
14
+ const onClick = (0, react_1.useCallback)(() => {
15
+ setEditorSnapping((current) => !current);
16
+ }, [setEditorSnapping]);
17
+ const color = editorSnapping ? colors_1.BLUE : colors_1.WHITE;
18
+ const accessibilityLabel = [
19
+ editorSnapping ? 'Disable snapping' : 'Enable snapping',
20
+ (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? null : '(Shift+M)',
21
+ ]
22
+ .filter(no_react_1.NoReactInternals.truthy)
23
+ .join(' ');
24
+ return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, "aria-pressed": editorSnapping, "aria-keyshortcuts": "Shift+M", onClick: onClick, children: jsx_runtime_1.jsx(magnet_1.MagnetIcon, { style: { width: 17, height: 17 }, fill: color, "aria-hidden": "true", focusable: "false" }) }));
25
+ };
26
+ exports.SnappingToggle = SnappingToggle;
@@ -14,7 +14,7 @@ export type TSplitterContext = {
14
14
  defaultFlex: number;
15
15
  id: string;
16
16
  persistFlex: (value: number) => void;
17
- isDragging: React.MutableRefObject<false | {
17
+ isDragging: React.RefObject<false | {
18
18
  x: number;
19
19
  y: number;
20
20
  }>;
@@ -12,6 +12,7 @@ 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
14
  const ExpandedTracksProvider_1 = require("../ExpandedTracksProvider");
15
+ const options_sidebar_tabs_1 = require("../options-sidebar-tabs");
15
16
  const get_node_keyframes_1 = require("./get-node-keyframes");
16
17
  const get_timeline_easing_segments_1 = require("./get-timeline-easing-segments");
17
18
  const timeline_expanded_filter_1 = require("./timeline-expanded-filter");
@@ -684,6 +685,7 @@ const TimelineSelectionProvider = ({ children }) => {
684
685
  if (!canSelectItem(item)) {
685
686
  return;
686
687
  }
688
+ (0, options_sidebar_tabs_1.selectOptionsSidebarInspectorPanel)();
687
689
  expandParentsForSelectionItem(item);
688
690
  if (options.reveal) {
689
691
  requestRevealSelectionItem(item);
@@ -714,6 +716,9 @@ const TimelineSelectionProvider = ({ children }) => {
714
716
  if (!items.every(canSelectItem)) {
715
717
  return;
716
718
  }
719
+ if (items.length > 0) {
720
+ (0, options_sidebar_tabs_1.selectOptionsSidebarInspectorPanel)();
721
+ }
717
722
  selectionScope.current = timelineSelectionScope;
718
723
  selectionAnchor.current =
719
724
  items.length === 0 ? null : items[items.length - 1];
@@ -8,8 +8,8 @@ const open_in_editor_1 = require("../../helpers/open-in-editor");
8
8
  const Fieldset_1 = require("../RenderModal/SchemaEditor/Fieldset");
9
9
  const source_attribution_1 = require("../Timeline/TimelineStack/source-attribution");
10
10
  const container = {
11
- paddingLeft: Fieldset_1.SCHEMA_EDITOR_FIELDSET_PADDING,
12
- paddingTop: Fieldset_1.SCHEMA_EDITOR_FIELDSET_PADDING / 2,
11
+ paddingLeft: (0, Fieldset_1.getSchemaEditorFieldsetPadding)(),
12
+ paddingTop: (0, Fieldset_1.getSchemaEditorFieldsetPadding)() / 2,
13
13
  };
14
14
  const ClickableFileName = ({ originalFileName, }) => {
15
15
  const [titleHovered, setTitleHovered] = (0, react_1.useState)(false);
@@ -37,15 +37,23 @@ exports.VisualControlsContent = void 0;
37
37
  const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const react_1 = __importStar(require("react"));
39
39
  const VisualControls_1 = require("../../visual-controls/VisualControls");
40
+ const InspectorPanelLayout_1 = require("../InspectorPanelLayout");
41
+ const Fieldset_1 = require("../RenderModal/SchemaEditor/Fieldset");
40
42
  const SchemaSeparationLine_1 = require("../RenderModal/SchemaEditor/SchemaSeparationLine");
41
43
  const VisualControlHandle_1 = require("./VisualControlHandle");
44
+ const rootInset = (0, Fieldset_1.getSchemaEditorRootInset)(InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING);
45
+ const container = {
46
+ boxSizing: 'border-box',
47
+ paddingLeft: rootInset,
48
+ paddingRight: rootInset,
49
+ };
42
50
  const VisualControlsContent = () => {
43
51
  const { handles } = (0, react_1.useContext)(VisualControls_1.VisualControlsContext);
44
52
  const entries = Object.entries(handles);
45
53
  if (entries.length === 0) {
46
54
  return null;
47
55
  }
48
- return (jsx_runtime_1.jsx("div", { children: entries.map(([key, value], i) => {
56
+ return (jsx_runtime_1.jsx("div", { style: container, children: entries.map(([key, value], i) => {
49
57
  return (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [
50
58
  jsx_runtime_1.jsx(VisualControlHandle_1.VisualControlHandle, { keyName: key, value: value }), i === entries.length - 1 ? null : jsx_runtime_1.jsx(SchemaSeparationLine_1.SchemaSeparationLine, {})] }, key));
51
59
  }) }));
@@ -8,7 +8,9 @@ const NotificationCenter_1 = require("./Notifications/NotificationCenter");
8
8
  const hasEffectDragType = (dataTransfer) => {
9
9
  const types = Array.from(dataTransfer.types);
10
10
  const hasExplicitEffectType = types.includes(studio_shared_1.EFFECT_DRAG_MIME_TYPE);
11
- if (!hasExplicitEffectType && hasImportableAssetDragType(dataTransfer)) {
11
+ if (!hasExplicitEffectType &&
12
+ (hasNonEffectRemotionDragType(dataTransfer) ||
13
+ hasNonRemotionImportableAssetDragType(dataTransfer))) {
12
14
  return false;
13
15
  }
14
16
  return types.some((type) => type === studio_shared_1.EFFECT_DRAG_MIME_TYPE || isGenericDragType(type));
@@ -21,14 +23,33 @@ exports.hasExplicitEffectDragType = hasExplicitEffectDragType;
21
23
  const isGenericDragType = (type) => {
22
24
  return type === 'application/json' || type === 'text/plain';
23
25
  };
24
- const hasImportableAssetDragType = (dataTransfer) => {
25
- return Array.from(dataTransfer.types).some((type) => type === 'Files' ||
26
- type === studio_shared_1.ASSET_DRAG_MIME_TYPE ||
27
- type === studio_shared_1.COMPOSITION_DRAG_MIME_TYPE ||
28
- type === studio_shared_1.COMPONENT_DRAG_MIME_TYPE ||
29
- type === studio_shared_1.SFX_DRAG_MIME_TYPE ||
30
- type === 'text/uri-list' ||
31
- type === 'text/html');
26
+ const isNonEffectRemotionDragType = (mimeType) => {
27
+ switch (mimeType) {
28
+ case studio_shared_1.EFFECT_DRAG_MIME_TYPE:
29
+ return false;
30
+ case studio_shared_1.ASSET_DRAG_MIME_TYPE:
31
+ case studio_shared_1.COMPOSITION_DRAG_MIME_TYPE:
32
+ case studio_shared_1.COMPONENT_DRAG_MIME_TYPE:
33
+ case studio_shared_1.ELEMENT_DRAG_MIME_TYPE:
34
+ case studio_shared_1.SFX_DRAG_MIME_TYPE:
35
+ return true;
36
+ default:
37
+ mimeType;
38
+ throw new Error(`Unhandled Remotion drag MIME type: ${mimeType}`);
39
+ }
40
+ };
41
+ const hasNonEffectRemotionDragType = (dataTransfer) => {
42
+ return Array.from(dataTransfer.types).some((type) => {
43
+ if (!(0, studio_shared_1.isRemotionDragMimeType)(type)) {
44
+ return false;
45
+ }
46
+ return isNonEffectRemotionDragType(type);
47
+ });
48
+ };
49
+ const hasNonRemotionImportableAssetDragType = (dataTransfer) => {
50
+ return Array.from(dataTransfer.types).some((type) => {
51
+ return type === 'Files' || type === 'text/uri-list' || type === 'text/html';
52
+ });
32
53
  };
33
54
  const getEffectDragData = (dataTransfer) => {
34
55
  for (const type of [
@@ -86,6 +86,6 @@ export declare const insertElement: ({ compositionFile, compositionId, dropPosit
86
86
  slug: string;
87
87
  displayName: string;
88
88
  sourceCode: string;
89
- dimensions: import("@remotion/studio-shared").ComponentDimensions;
89
+ dimensions: import("@remotion/studio-shared").ComponentDimensions | null;
90
90
  };
91
91
  }) => Promise<void>;
@@ -2,3 +2,4 @@ export declare const optionsSidebarTabs: import("react").RefObject<{
2
2
  selectInspectorPanel: () => void;
3
3
  selectRendersPanel: () => void;
4
4
  } | null>;
5
+ export declare const selectOptionsSidebarInspectorPanel: () => void;
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.optionsSidebarTabs = void 0;
3
+ exports.selectOptionsSidebarInspectorPanel = exports.optionsSidebarTabs = void 0;
4
4
  const react_1 = require("react");
5
5
  exports.optionsSidebarTabs = (0, react_1.createRef)();
6
+ const selectOptionsSidebarInspectorPanel = () => {
7
+ var _a;
8
+ (_a = exports.optionsSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectInspectorPanel();
9
+ };
10
+ exports.selectOptionsSidebarInspectorPanel = selectOptionsSidebarInspectorPanel;
@@ -0,0 +1,36 @@
1
+ import type { Guide } from '../state/editor-guides';
2
+ import type { SelectedOutline } from './selected-outline-geometry';
3
+ export declare const selectedOutlineSnapThresholdPx = 10;
4
+ export declare const selectedOutlineSnapIndicatorColor = "#ff00ff";
5
+ export type SelectedOutlineSnapAxis = 'x' | 'y';
6
+ export type SelectedOutlineSnapTargetType = 'canvas-left' | 'canvas-right' | 'canvas-top' | 'canvas-bottom' | 'canvas-horizontal-center' | 'canvas-vertical-center' | 'guide-vertical' | 'guide-horizontal';
7
+ export type SelectedOutlineSnapTarget = {
8
+ readonly axis: SelectedOutlineSnapAxis;
9
+ readonly position: number;
10
+ readonly type: SelectedOutlineSnapTargetType;
11
+ };
12
+ export type SelectedOutlineSnapEdge = 'left' | 'right' | 'center-x' | 'top' | 'bottom' | 'center-y';
13
+ export type SelectedOutlineSnapPoint = {
14
+ readonly distance: number;
15
+ readonly edge: SelectedOutlineSnapEdge;
16
+ readonly target: SelectedOutlineSnapTarget;
17
+ };
18
+ export type SelectedOutlineSnapResult = {
19
+ readonly activeSnapPoints: readonly SelectedOutlineSnapPoint[];
20
+ readonly snapOffsetX: number | null;
21
+ readonly snapOffsetY: number | null;
22
+ };
23
+ export declare const getSelectedOutlineSnapTargets: ({ compositionHeight, compositionWidth, guides, }: {
24
+ readonly compositionHeight: number;
25
+ readonly compositionWidth: number;
26
+ readonly guides: readonly Guide[];
27
+ }) => readonly SelectedOutlineSnapTarget[];
28
+ export declare const findSelectedOutlineSnap: ({ allowX, allowY, deltaX, deltaY, outlines, scale, targets, }: {
29
+ readonly allowX: boolean;
30
+ readonly allowY: boolean;
31
+ readonly deltaX: number;
32
+ readonly deltaY: number;
33
+ readonly outlines: readonly SelectedOutline[];
34
+ readonly scale: number;
35
+ readonly targets: readonly SelectedOutlineSnapTarget[];
36
+ }) => SelectedOutlineSnapResult;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findSelectedOutlineSnap = exports.getSelectedOutlineSnapTargets = exports.selectedOutlineSnapIndicatorColor = exports.selectedOutlineSnapThresholdPx = void 0;
4
+ exports.selectedOutlineSnapThresholdPx = 10;
5
+ exports.selectedOutlineSnapIndicatorColor = '#ff00ff';
6
+ const EPSILON = 0.000001;
7
+ const getSelectedOutlineSnapTargets = ({ compositionHeight, compositionWidth, guides, }) => {
8
+ return [
9
+ { axis: 'x', position: 0, type: 'canvas-left' },
10
+ {
11
+ axis: 'x',
12
+ position: compositionWidth / 2,
13
+ type: 'canvas-horizontal-center',
14
+ },
15
+ { axis: 'x', position: compositionWidth, type: 'canvas-right' },
16
+ { axis: 'y', position: 0, type: 'canvas-top' },
17
+ {
18
+ axis: 'y',
19
+ position: compositionHeight / 2,
20
+ type: 'canvas-vertical-center',
21
+ },
22
+ { axis: 'y', position: compositionHeight, type: 'canvas-bottom' },
23
+ ...guides.flatMap((guide) => {
24
+ if (!guide.show) {
25
+ return [];
26
+ }
27
+ return [
28
+ guide.orientation === 'vertical'
29
+ ? {
30
+ axis: 'x',
31
+ position: guide.position,
32
+ type: 'guide-vertical',
33
+ }
34
+ : {
35
+ axis: 'y',
36
+ position: guide.position,
37
+ type: 'guide-horizontal',
38
+ },
39
+ ];
40
+ }),
41
+ ];
42
+ };
43
+ exports.getSelectedOutlineSnapTargets = getSelectedOutlineSnapTargets;
44
+ const getSelectedOutlineBounds = ({ deltaX, deltaY, outlines, scale, }) => {
45
+ if (outlines.length === 0) {
46
+ return null;
47
+ }
48
+ const points = outlines.flatMap((outline) => outline.points);
49
+ const left = Math.min(...points.map((point) => point.x)) / scale + deltaX;
50
+ const right = Math.max(...points.map((point) => point.x)) / scale + deltaX;
51
+ const top = Math.min(...points.map((point) => point.y)) / scale + deltaY;
52
+ const bottom = Math.max(...points.map((point) => point.y)) / scale + deltaY;
53
+ return {
54
+ left,
55
+ right,
56
+ top,
57
+ bottom,
58
+ centerX: left + (right - left) / 2,
59
+ centerY: top + (bottom - top) / 2,
60
+ };
61
+ };
62
+ const canSnapEdgeToTarget = (edge, target) => {
63
+ if (target.type === 'canvas-horizontal-center') {
64
+ return edge === 'center-x';
65
+ }
66
+ if (target.type === 'canvas-vertical-center') {
67
+ return edge === 'center-y';
68
+ }
69
+ if (target.type === 'canvas-left' || target.type === 'canvas-right') {
70
+ return edge === 'left' || edge === 'right';
71
+ }
72
+ if (target.type === 'guide-vertical') {
73
+ return edge === 'left' || edge === 'right' || edge === 'center-x';
74
+ }
75
+ if (target.type === 'canvas-top' || target.type === 'canvas-bottom') {
76
+ return edge === 'top' || edge === 'bottom';
77
+ }
78
+ return edge === 'top' || edge === 'bottom' || edge === 'center-y';
79
+ };
80
+ const findBestSnapForAxis = ({ edges, targets, threshold, }) => {
81
+ var _a;
82
+ let bestDistance = Infinity;
83
+ let bestSnaps = [];
84
+ for (const target of targets) {
85
+ for (const edge of edges) {
86
+ if (!canSnapEdgeToTarget(edge.edge, target)) {
87
+ continue;
88
+ }
89
+ const distance = Math.abs(edge.position - target.position);
90
+ if (distance > threshold || distance > bestDistance + EPSILON) {
91
+ continue;
92
+ }
93
+ if (distance < bestDistance - EPSILON) {
94
+ bestSnaps = [];
95
+ bestDistance = distance;
96
+ }
97
+ bestSnaps.push({
98
+ offset: target.position - edge.position,
99
+ snapPoint: {
100
+ distance,
101
+ edge: edge.edge,
102
+ target,
103
+ },
104
+ });
105
+ }
106
+ }
107
+ if (bestSnaps.length > 1) {
108
+ const centerSnap = bestSnaps.find((snap) => snap.snapPoint.target.type === 'canvas-horizontal-center' ||
109
+ snap.snapPoint.target.type === 'canvas-vertical-center');
110
+ if (centerSnap) {
111
+ return centerSnap;
112
+ }
113
+ }
114
+ return (_a = bestSnaps[0]) !== null && _a !== void 0 ? _a : null;
115
+ };
116
+ const findSelectedOutlineSnap = ({ allowX, allowY, deltaX, deltaY, outlines, scale, targets, }) => {
117
+ var _a, _b, _c, _d;
118
+ const bounds = getSelectedOutlineBounds({ deltaX, deltaY, outlines, scale });
119
+ if (bounds === null) {
120
+ return {
121
+ activeSnapPoints: [],
122
+ snapOffsetX: null,
123
+ snapOffsetY: null,
124
+ };
125
+ }
126
+ const threshold = exports.selectedOutlineSnapThresholdPx / scale;
127
+ const snapX = allowX
128
+ ? findBestSnapForAxis({
129
+ edges: [
130
+ { edge: 'left', position: bounds.left },
131
+ { edge: 'center-x', position: bounds.centerX },
132
+ { edge: 'right', position: bounds.right },
133
+ ],
134
+ targets: targets.filter((target) => target.axis === 'x'),
135
+ threshold,
136
+ })
137
+ : null;
138
+ const snapY = allowY
139
+ ? findBestSnapForAxis({
140
+ edges: [
141
+ { edge: 'top', position: bounds.top },
142
+ { edge: 'center-y', position: bounds.centerY },
143
+ { edge: 'bottom', position: bounds.bottom },
144
+ ],
145
+ targets: targets.filter((target) => target.axis === 'y'),
146
+ threshold,
147
+ })
148
+ : null;
149
+ return {
150
+ activeSnapPoints: [
151
+ (_a = snapX === null || snapX === void 0 ? void 0 : snapX.snapPoint) !== null && _a !== void 0 ? _a : null,
152
+ (_b = snapY === null || snapY === void 0 ? void 0 : snapY.snapPoint) !== null && _b !== void 0 ? _b : null,
153
+ ].filter((snapPoint) => snapPoint !== null),
154
+ snapOffsetX: (_c = snapX === null || snapX === void 0 ? void 0 : snapX.offset) !== null && _c !== void 0 ? _c : null,
155
+ snapOffsetY: (_d = snapY === null || snapY === void 0 ? void 0 : snapY.offset) !== null && _d !== void 0 ? _d : null,
156
+ };
157
+ };
158
+ exports.findSelectedOutlineSnap = findSelectedOutlineSnap;