@remotion/studio 4.0.432 → 4.0.433
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.
- package/dist/Studio.js +1 -3
- package/dist/components/CompositionSelector.js +16 -9
- package/dist/components/CurrentComposition.js +2 -5
- package/dist/components/EditorContent.js +4 -5
- package/dist/components/NewComposition/DuplicateComposition.js +4 -1
- package/dist/components/NewComposition/InputDragger.d.ts +1 -0
- package/dist/components/NewComposition/InputDragger.js +27 -8
- package/dist/components/OptionsPanel.js +1 -1
- package/dist/components/PlaybackRatePersistor.js +1 -1
- package/dist/components/PreviewToolbar.js +4 -2
- package/dist/components/RenderModal/SchemaEditor/SchemaLabel.js +3 -1
- package/dist/components/RenderModal/SchemaEditor/ZodArrayEditor.js +3 -1
- package/dist/components/RenderModal/SchemaEditor/ZodFieldValidation.js +3 -1
- package/dist/components/RenderModal/SchemaEditor/ZodTupleEditor.js +3 -1
- package/dist/components/RenderModal/WebRenderModalAudio.js +2 -0
- package/dist/components/RenderModal/WebRenderModalBasic.js +8 -1
- package/dist/components/RendersTab.js +1 -9
- package/dist/components/Timeline/TimelineBooleanField.d.ts +9 -0
- package/dist/components/Timeline/TimelineBooleanField.js +20 -0
- package/dist/components/Timeline/TimelineEmptyState.d.ts +2 -0
- package/dist/components/Timeline/TimelineEmptyState.js +15 -0
- package/dist/components/Timeline/TimelineExpandedSection.d.ts +5 -0
- package/dist/components/Timeline/TimelineExpandedSection.js +45 -7
- package/dist/components/Timeline/TimelineFieldRow.d.ts +3 -0
- package/dist/components/Timeline/TimelineFieldRow.js +17 -12
- package/dist/components/Timeline/TimelineListItem.d.ts +1 -0
- package/dist/components/Timeline/TimelineListItem.js +7 -7
- package/dist/components/Timeline/TimelineNumberField.d.ts +11 -0
- package/dist/components/Timeline/TimelineNumberField.js +53 -0
- package/dist/components/Timeline/TimelinePlayCursorSyncer.js +1 -1
- package/dist/components/Timeline/TimelineRotationField.d.ts +11 -0
- package/dist/components/Timeline/TimelineRotationField.js +64 -0
- package/dist/components/Timeline/TimelineSchemaField.d.ts +1 -3
- package/dist/components/Timeline/TimelineSchemaField.js +19 -74
- package/dist/components/Timeline/TimelineTranslateField.d.ts +11 -0
- package/dist/components/Timeline/TimelineTranslateField.js +115 -0
- package/dist/components/Timeline/timeline-field-utils.d.ts +2 -0
- package/dist/components/Timeline/timeline-field-utils.js +12 -0
- package/dist/components/Timeline/use-sequence-props-subscription.d.ts +2 -1
- package/dist/components/Timeline/use-sequence-props-subscription.js +32 -12
- package/dist/esm/{chunk-t28xqw5n.js → chunk-bd1bkakk.js} +2697 -2266
- package/dist/esm/internals.mjs +2697 -2266
- package/dist/esm/previewEntry.mjs +2702 -2271
- package/dist/esm/renderEntry.mjs +1 -3
- package/dist/helpers/calculate-timeline.js +17 -11
- package/dist/helpers/get-timeline-sequence-sort-key.d.ts +1 -1
- package/dist/helpers/get-timeline-sequence-sort-key.js +6 -3
- package/dist/helpers/inject-css.js +6 -1
- package/dist/helpers/sort-by-nonce-history.d.ts +5 -0
- package/dist/helpers/sort-by-nonce-history.js +73 -0
- package/dist/helpers/timeline-layout.js +8 -2
- package/dist/renderEntry.js +2 -2
- package/package.json +11 -11
|
@@ -5,25 +5,28 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const remotion_1 = require("remotion");
|
|
7
7
|
const call_api_1 = require("../call-api");
|
|
8
|
+
const TimelineExpandedSection_1 = require("./TimelineExpandedSection");
|
|
9
|
+
const TimelineListItem_1 = require("./TimelineListItem");
|
|
8
10
|
const TimelineSchemaField_1 = require("./TimelineSchemaField");
|
|
9
|
-
const
|
|
11
|
+
const FIELD_ROW_PADDING_LEFT = 24;
|
|
12
|
+
const fieldRowBase = {
|
|
10
13
|
display: 'flex',
|
|
11
14
|
alignItems: 'center',
|
|
12
15
|
gap: 8,
|
|
13
|
-
|
|
16
|
+
paddingRight: TimelineExpandedSection_1.EXPANDED_SECTION_PADDING_RIGHT,
|
|
14
17
|
};
|
|
15
18
|
const fieldName = {
|
|
16
19
|
fontSize: 12,
|
|
17
20
|
color: 'rgba(255, 255, 255, 0.8)',
|
|
18
21
|
};
|
|
19
22
|
const fieldLabelRow = {
|
|
20
|
-
flex:
|
|
23
|
+
flex: '0 0 50%',
|
|
21
24
|
display: 'flex',
|
|
22
25
|
flexDirection: 'row',
|
|
23
26
|
alignItems: 'center',
|
|
24
27
|
gap: 6,
|
|
25
28
|
};
|
|
26
|
-
const TimelineFieldRow = ({ field, overrideId, validatedLocation }) => {
|
|
29
|
+
const TimelineFieldRow = ({ field, overrideId, validatedLocation, nestedDepth, nodePath }) => {
|
|
27
30
|
var _a, _b, _c, _d;
|
|
28
31
|
const { setDragOverrides, clearDragOverrides, dragOverrides, codeValues: allPropStatuses, } = (0, react_1.useContext)(remotion_1.Internals.VisualModeOverridesContext);
|
|
29
32
|
const propStatuses = ((_a = allPropStatuses[overrideId]) !== null && _a !== void 0 ? _a : null);
|
|
@@ -37,9 +40,10 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation }) => {
|
|
|
37
40
|
runtimeValue: field.currentValue,
|
|
38
41
|
dragOverrideValue,
|
|
39
42
|
defaultValue: field.fieldSchema.default,
|
|
43
|
+
shouldResortToDefaultValueIfUndefined: true,
|
|
40
44
|
});
|
|
41
45
|
const onSave = (0, react_1.useCallback)((key, value) => {
|
|
42
|
-
if (!propStatuses || !validatedLocation) {
|
|
46
|
+
if (!propStatuses || !validatedLocation || !nodePath) {
|
|
43
47
|
return Promise.reject(new Error('Cannot save'));
|
|
44
48
|
}
|
|
45
49
|
const status = propStatuses[key];
|
|
@@ -51,14 +55,12 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation }) => {
|
|
|
51
55
|
: null;
|
|
52
56
|
return (0, call_api_1.callApi)('/api/save-sequence-props', {
|
|
53
57
|
fileName: validatedLocation.source,
|
|
54
|
-
|
|
55
|
-
column: validatedLocation.column,
|
|
58
|
+
nodePath,
|
|
56
59
|
key,
|
|
57
60
|
value: JSON.stringify(value),
|
|
58
|
-
enumPaths: [],
|
|
59
61
|
defaultValue,
|
|
60
62
|
}).then(() => undefined);
|
|
61
|
-
}, [propStatuses, validatedLocation, field.fieldSchema.default]);
|
|
63
|
+
}, [propStatuses, validatedLocation, nodePath, field.fieldSchema.default]);
|
|
62
64
|
const onDragValueChange = (0, react_1.useCallback)((key, value) => {
|
|
63
65
|
setDragOverrides(overrideId, key, value);
|
|
64
66
|
}, [setDragOverrides, overrideId]);
|
|
@@ -67,12 +69,15 @@ const TimelineFieldRow = ({ field, overrideId, validatedLocation }) => {
|
|
|
67
69
|
}, [clearDragOverrides, overrideId]);
|
|
68
70
|
const style = (0, react_1.useMemo)(() => {
|
|
69
71
|
return {
|
|
70
|
-
...
|
|
72
|
+
...fieldRowBase,
|
|
71
73
|
height: field.rowHeight,
|
|
74
|
+
paddingLeft: TimelineExpandedSection_1.EXPANDED_SECTION_PADDING_LEFT +
|
|
75
|
+
FIELD_ROW_PADDING_LEFT +
|
|
76
|
+
TimelineListItem_1.SPACING * 3 * nestedDepth,
|
|
72
77
|
};
|
|
73
|
-
}, [field.rowHeight]);
|
|
78
|
+
}, [field.rowHeight, nestedDepth]);
|
|
74
79
|
return (jsx_runtime_1.jsxs("div", { style: style, children: [
|
|
75
|
-
jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_c = field.description) !== null && _c !== void 0 ? _c : field.key }) }), jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: propStatus, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, canUpdate: (_d = propStatus === null || propStatus === void 0 ? void 0 : propStatus.canUpdate) !== null && _d !== void 0 ? _d : false, effectiveValue: effectiveValue })
|
|
80
|
+
jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_c = field.description) !== null && _c !== void 0 ? _c : field.key }) }), jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: propStatus, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, canUpdate: (_d = propStatus === null || propStatus === void 0 ? void 0 : propStatus.canUpdate) !== null && _d !== void 0 ? _d : false, effectiveValue: effectiveValue, codeValue: propStatus })
|
|
76
81
|
] }));
|
|
77
82
|
};
|
|
78
83
|
exports.TimelineFieldRow = TimelineFieldRow;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TimelineListItem = void 0;
|
|
3
|
+
exports.TimelineListItem = exports.SPACING = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const remotion_1 = require("remotion");
|
|
@@ -13,9 +13,9 @@ const TimelineLayerEye_1 = require("./TimelineLayerEye");
|
|
|
13
13
|
const TimelineStack_1 = require("./TimelineStack");
|
|
14
14
|
const use_resolved_stack_1 = require("./use-resolved-stack");
|
|
15
15
|
const use_sequence_props_subscription_1 = require("./use-sequence-props-subscription");
|
|
16
|
-
|
|
16
|
+
exports.SPACING = 5;
|
|
17
17
|
const space = {
|
|
18
|
-
width: SPACING,
|
|
18
|
+
width: exports.SPACING,
|
|
19
19
|
flexShrink: 0,
|
|
20
20
|
};
|
|
21
21
|
const arrowButton = {
|
|
@@ -44,14 +44,14 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
|
|
|
44
44
|
const { hidden, setHidden } = (0, react_1.useContext)(remotion_1.Internals.SequenceVisibilityToggleContext);
|
|
45
45
|
const { expandedTracks, toggleTrack } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksContext);
|
|
46
46
|
const originalLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = sequence.stack) !== null && _a !== void 0 ? _a : null);
|
|
47
|
-
(0, use_sequence_props_subscription_1.useSequencePropsSubscription)(sequence, originalLocation);
|
|
47
|
+
const nodePath = (0, use_sequence_props_subscription_1.useSequencePropsSubscription)(sequence, originalLocation);
|
|
48
48
|
const isExpanded = visualModeEnabled && ((_b = expandedTracks[sequence.id]) !== null && _b !== void 0 ? _b : false);
|
|
49
49
|
const onToggleExpand = (0, react_1.useCallback)(() => {
|
|
50
50
|
toggleTrack(sequence.id);
|
|
51
51
|
}, [sequence.id, toggleTrack]);
|
|
52
52
|
const padder = (0, react_1.useMemo)(() => {
|
|
53
53
|
return {
|
|
54
|
-
width: Number(SPACING *
|
|
54
|
+
width: Number(exports.SPACING * 3) * nestedDepth,
|
|
55
55
|
flexShrink: 0,
|
|
56
56
|
};
|
|
57
57
|
}, [nestedDepth]);
|
|
@@ -78,7 +78,7 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
|
|
|
78
78
|
alignItems: 'center',
|
|
79
79
|
wordBreak: 'break-all',
|
|
80
80
|
textAlign: 'left',
|
|
81
|
-
paddingLeft: SPACING,
|
|
81
|
+
paddingLeft: exports.SPACING,
|
|
82
82
|
borderBottom: `1px solid ${colors_1.TIMELINE_TRACK_SEPARATOR}`,
|
|
83
83
|
};
|
|
84
84
|
}, [sequence.type]);
|
|
@@ -91,6 +91,6 @@ const TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
|
|
|
91
91
|
return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
|
|
92
92
|
jsx_runtime_1.jsxs("div", { style: outer, children: [
|
|
93
93
|
jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: sequence.type === 'audio' ? 'speaker' : 'eye', hidden: isItemHidden, onInvoked: onToggleVisibility }), jsx_runtime_1.jsx("div", { style: padder }), sequence.parent && nestedDepth > 0 ? jsx_runtime_1.jsx("div", { style: space }) : null, visualModeEnabled ? (sequence.controls ? (jsx_runtime_1.jsx("button", { type: "button", style: arrowStyle, onClick: onToggleExpand, "aria-expanded": isExpanded, "aria-label": `${isExpanded ? 'Collapse' : 'Expand'} track`, children: jsx_runtime_1.jsx("svg", { width: "12", height: "12", viewBox: "0 0 8 8", style: { display: 'block' }, children: jsx_runtime_1.jsx("path", { d: "M2 1L6 4L2 7Z", fill: "white" }) }) })) : (jsx_runtime_1.jsx("div", { style: arrowButton }))) : null, jsx_runtime_1.jsx(TimelineStack_1.TimelineStack, { sequence: sequence, isCompact: isCompact, originalLocation: originalLocation })
|
|
94
|
-
] }), visualModeEnabled && isExpanded && sequence.controls ? (jsx_runtime_1.jsx(TimelineExpandedSection_1.TimelineExpandedSection, { sequence: sequence, originalLocation: originalLocation })) : null] }));
|
|
94
|
+
] }), visualModeEnabled && isExpanded && sequence.controls ? (jsx_runtime_1.jsx(TimelineExpandedSection_1.TimelineExpandedSection, { sequence: sequence, originalLocation: originalLocation, nestedDepth: nestedDepth, nodePath: nodePath })) : null] }));
|
|
95
95
|
};
|
|
96
96
|
exports.TimelineListItem = TimelineListItem;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SchemaFieldInfo } from '../../helpers/timeline-layout';
|
|
3
|
+
export declare const TimelineNumberField: React.FC<{
|
|
4
|
+
readonly field: SchemaFieldInfo;
|
|
5
|
+
readonly effectiveValue: unknown;
|
|
6
|
+
readonly codeValue: unknown;
|
|
7
|
+
readonly canUpdate: boolean;
|
|
8
|
+
readonly onSave: (key: string, value: unknown) => Promise<void>;
|
|
9
|
+
readonly onDragValueChange: (key: string, value: unknown) => void;
|
|
10
|
+
readonly onDragEnd: () => void;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineNumberField = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const InputDragger_1 = require("../NewComposition/InputDragger");
|
|
7
|
+
const timeline_field_utils_1 = require("./timeline-field-utils");
|
|
8
|
+
const TimelineNumberField = ({ field, effectiveValue, canUpdate, onSave, onDragValueChange, onDragEnd, codeValue, }) => {
|
|
9
|
+
var _a, _b, _c;
|
|
10
|
+
const [dragValue, setDragValue] = (0, react_1.useState)(null);
|
|
11
|
+
const onValueChange = (0, react_1.useCallback)((newVal) => {
|
|
12
|
+
setDragValue(newVal);
|
|
13
|
+
onDragValueChange(field.key, newVal);
|
|
14
|
+
}, [onDragValueChange, field.key]);
|
|
15
|
+
(0, react_1.useEffect)(() => {
|
|
16
|
+
setDragValue(null);
|
|
17
|
+
onDragEnd();
|
|
18
|
+
}, [field.currentValue, onDragEnd]);
|
|
19
|
+
const onValueChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
20
|
+
if (canUpdate && newVal !== codeValue) {
|
|
21
|
+
onSave(field.key, newVal).catch(() => {
|
|
22
|
+
setDragValue(null);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
setDragValue(null);
|
|
27
|
+
}
|
|
28
|
+
}, [canUpdate, onSave, field.key, codeValue]);
|
|
29
|
+
const onTextChange = (0, react_1.useCallback)((newVal) => {
|
|
30
|
+
if (canUpdate) {
|
|
31
|
+
const parsed = Number(newVal);
|
|
32
|
+
if (!Number.isNaN(parsed) && parsed !== codeValue) {
|
|
33
|
+
setDragValue(parsed);
|
|
34
|
+
onSave(field.key, parsed).catch(() => {
|
|
35
|
+
setDragValue(null);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}, [canUpdate, onSave, field.key, codeValue]);
|
|
40
|
+
const step = field.fieldSchema.type === 'number' ? ((_a = field.fieldSchema.step) !== null && _a !== void 0 ? _a : 1) : 1;
|
|
41
|
+
const stepDecimals = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getDecimalPlaces)(step), [step]);
|
|
42
|
+
const formatter = (0, react_1.useCallback)((v) => {
|
|
43
|
+
const num = Number(v);
|
|
44
|
+
const digits = Math.max(stepDecimals, (0, timeline_field_utils_1.getDecimalPlaces)(num));
|
|
45
|
+
return digits === 0 ? String(num) : num.toFixed(digits);
|
|
46
|
+
}, [stepDecimals]);
|
|
47
|
+
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'
|
|
48
|
+
? ((_b = field.fieldSchema.min) !== null && _b !== void 0 ? _b : -Infinity)
|
|
49
|
+
: -Infinity, max: field.fieldSchema.type === 'number'
|
|
50
|
+
? ((_c = field.fieldSchema.max) !== null && _c !== void 0 ? _c : Infinity)
|
|
51
|
+
: Infinity, step: step, formatter: formatter, rightAlign: false }));
|
|
52
|
+
};
|
|
53
|
+
exports.TimelineNumberField = TimelineNumberField;
|
|
@@ -11,7 +11,7 @@ let lastTimelinePositionWhileScrolling = null;
|
|
|
11
11
|
const TimelinePlayCursorSyncer = () => {
|
|
12
12
|
var _a, _b;
|
|
13
13
|
const video = remotion_1.Internals.useVideo();
|
|
14
|
-
const timelineContext =
|
|
14
|
+
const timelineContext = remotion_1.Internals.useTimelineContext();
|
|
15
15
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
16
16
|
const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
17
17
|
const { zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SchemaFieldInfo } from '../../helpers/timeline-layout';
|
|
3
|
+
export declare const TimelineRotationField: React.FC<{
|
|
4
|
+
readonly field: SchemaFieldInfo;
|
|
5
|
+
readonly effectiveValue: unknown;
|
|
6
|
+
readonly codeValue: unknown;
|
|
7
|
+
readonly canUpdate: boolean;
|
|
8
|
+
readonly onSave: (key: string, value: unknown) => Promise<void>;
|
|
9
|
+
readonly onDragValueChange: (key: string, value: unknown) => void;
|
|
10
|
+
readonly onDragEnd: () => void;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineRotationField = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const InputDragger_1 = require("../NewComposition/InputDragger");
|
|
7
|
+
const timeline_field_utils_1 = require("./timeline-field-utils");
|
|
8
|
+
const parseCssRotationToDegrees = (value) => {
|
|
9
|
+
try {
|
|
10
|
+
const m = new DOMMatrix(`rotate(${value})`);
|
|
11
|
+
return Math.round(Math.atan2(m.b, m.a) * (180 / Math.PI) * 1e6) / 1e6;
|
|
12
|
+
}
|
|
13
|
+
catch (_a) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const TimelineRotationField = ({ field, effectiveValue, codeValue, canUpdate, onSave, onDragValueChange, onDragEnd, }) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const [dragValue, setDragValue] = (0, react_1.useState)(null);
|
|
20
|
+
const degrees = (0, react_1.useMemo)(() => parseCssRotationToDegrees(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0deg')), [effectiveValue]);
|
|
21
|
+
const onValueChange = (0, react_1.useCallback)((newVal) => {
|
|
22
|
+
setDragValue(newVal);
|
|
23
|
+
onDragValueChange(field.key, `${newVal}deg`);
|
|
24
|
+
}, [onDragValueChange, field.key]);
|
|
25
|
+
(0, react_1.useEffect)(() => {
|
|
26
|
+
setDragValue(null);
|
|
27
|
+
onDragEnd();
|
|
28
|
+
}, [field.currentValue, onDragEnd]);
|
|
29
|
+
const onValueChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
30
|
+
const newStr = `${newVal}deg`;
|
|
31
|
+
if (canUpdate && newStr !== codeValue) {
|
|
32
|
+
onSave(field.key, newStr).catch(() => {
|
|
33
|
+
setDragValue(null);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
setDragValue(null);
|
|
38
|
+
}
|
|
39
|
+
}, [canUpdate, onSave, field.key, codeValue]);
|
|
40
|
+
const onTextChange = (0, react_1.useCallback)((newVal) => {
|
|
41
|
+
if (canUpdate) {
|
|
42
|
+
const parsed = Number(newVal);
|
|
43
|
+
if (!Number.isNaN(parsed)) {
|
|
44
|
+
const newStr = `${parsed}deg`;
|
|
45
|
+
if (newStr !== codeValue) {
|
|
46
|
+
setDragValue(parsed);
|
|
47
|
+
onSave(field.key, newStr).catch(() => {
|
|
48
|
+
setDragValue(null);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}, [canUpdate, onSave, field.key, codeValue]);
|
|
54
|
+
const step = field.fieldSchema.type === 'rotation' ? ((_a = field.fieldSchema.step) !== null && _a !== void 0 ? _a : 1) : 1;
|
|
55
|
+
const stepDecimals = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getDecimalPlaces)(step), [step]);
|
|
56
|
+
const formatter = (0, react_1.useCallback)((v) => {
|
|
57
|
+
const num = Number(v);
|
|
58
|
+
const digits = Math.max(stepDecimals, (0, timeline_field_utils_1.getDecimalPlaces)(num));
|
|
59
|
+
const formatted = digits === 0 ? String(num) : num.toFixed(digits);
|
|
60
|
+
return `${formatted}\u00B0`;
|
|
61
|
+
}, [stepDecimals]);
|
|
62
|
+
return (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: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false }));
|
|
63
|
+
};
|
|
64
|
+
exports.TimelineRotationField = TimelineRotationField;
|
|
@@ -8,8 +8,6 @@ export declare const TimelineFieldValue: React.FC<{
|
|
|
8
8
|
readonly onDragEnd: () => void;
|
|
9
9
|
readonly canUpdate: boolean;
|
|
10
10
|
readonly propStatus: CanUpdateSequencePropStatus | null;
|
|
11
|
+
readonly codeValue: unknown;
|
|
11
12
|
readonly effectiveValue: unknown;
|
|
12
13
|
}>;
|
|
13
|
-
export declare const TimelineFieldSavingSpinner: React.FC<{
|
|
14
|
-
readonly saving: boolean;
|
|
15
|
-
}>;
|
|
@@ -1,79 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.TimelineFieldValue = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
5
|
+
const TimelineBooleanField_1 = require("./TimelineBooleanField");
|
|
6
|
+
const TimelineNumberField_1 = require("./TimelineNumberField");
|
|
7
|
+
const TimelineRotationField_1 = require("./TimelineRotationField");
|
|
8
|
+
const TimelineTranslateField_1 = require("./TimelineTranslateField");
|
|
9
9
|
const unsupportedLabel = {
|
|
10
10
|
color: 'rgba(255, 255, 255, 0.4)',
|
|
11
11
|
fontSize: 12,
|
|
12
|
-
marginLeft: 'auto',
|
|
13
12
|
fontStyle: 'italic',
|
|
14
13
|
};
|
|
15
|
-
const draggerStyle = {
|
|
16
|
-
width: 80,
|
|
17
|
-
marginLeft: 'auto',
|
|
18
|
-
};
|
|
19
|
-
const checkboxContainer = {
|
|
20
|
-
marginLeft: 'auto',
|
|
21
|
-
};
|
|
22
14
|
const notEditableBackground = {
|
|
23
15
|
backgroundColor: 'rgba(255, 0, 0, 0.2)',
|
|
24
16
|
borderRadius: 3,
|
|
25
17
|
padding: '0 4px',
|
|
26
18
|
};
|
|
27
|
-
const
|
|
28
|
-
var _a, _b, _c;
|
|
29
|
-
const [dragValue, setDragValue] = (0, react_1.useState)(null);
|
|
30
|
-
const dragging = (0, react_1.useRef)(false);
|
|
31
|
-
const onValueChange = (0, react_1.useCallback)((newVal) => {
|
|
32
|
-
dragging.current = true;
|
|
33
|
-
setDragValue(newVal);
|
|
34
|
-
onDragValueChange(field.key, newVal);
|
|
35
|
-
}, [onDragValueChange, field.key]);
|
|
36
|
-
(0, react_1.useEffect)(() => {
|
|
37
|
-
setDragValue(null);
|
|
38
|
-
onDragEnd();
|
|
39
|
-
}, [field.currentValue, onDragEnd]);
|
|
40
|
-
const onValueChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
41
|
-
if (canUpdate && newVal !== codeValue) {
|
|
42
|
-
onSave(field.key, newVal).catch(() => {
|
|
43
|
-
setDragValue(null);
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
setDragValue(null);
|
|
48
|
-
}
|
|
49
|
-
}, [canUpdate, onSave, field.key, codeValue]);
|
|
50
|
-
const onTextChange = (0, react_1.useCallback)((newVal) => {
|
|
51
|
-
if (canUpdate) {
|
|
52
|
-
const parsed = Number(newVal);
|
|
53
|
-
if (!Number.isNaN(parsed) && parsed !== codeValue) {
|
|
54
|
-
setDragValue(parsed);
|
|
55
|
-
onSave(field.key, parsed).catch(() => {
|
|
56
|
-
setDragValue(null);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}, [canUpdate, onSave, field.key, codeValue]);
|
|
61
|
-
return (jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragValue !== null && dragValue !== void 0 ? dragValue : codeValue, style: draggerStyle, status: "ok", onValueChange: onValueChange, onValueChangeEnd: onValueChangeEnd, onTextChange: onTextChange, min: field.fieldSchema.type === 'number'
|
|
62
|
-
? ((_a = field.fieldSchema.min) !== null && _a !== void 0 ? _a : -Infinity)
|
|
63
|
-
: -Infinity, max: field.fieldSchema.type === 'number'
|
|
64
|
-
? ((_b = field.fieldSchema.max) !== null && _b !== void 0 ? _b : Infinity)
|
|
65
|
-
: Infinity, step: field.fieldSchema.type === 'number' ? ((_c = field.fieldSchema.step) !== null && _c !== void 0 ? _c : 1) : 1, rightAlign: true }));
|
|
66
|
-
};
|
|
67
|
-
const TimelineBooleanField = ({ field, codeValue, canUpdate, onSave }) => {
|
|
68
|
-
const checked = Boolean(codeValue);
|
|
69
|
-
const onChange = (0, react_1.useCallback)(() => {
|
|
70
|
-
if (canUpdate) {
|
|
71
|
-
onSave(field.key, !checked);
|
|
72
|
-
}
|
|
73
|
-
}, [canUpdate, onSave, field.key, checked]);
|
|
74
|
-
return (jsx_runtime_1.jsx("div", { style: checkboxContainer, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: checked, onChange: onChange, name: field.key, disabled: !canUpdate }) }));
|
|
75
|
-
};
|
|
76
|
-
const TimelineFieldValue = ({ field, onSave, onDragValueChange, onDragEnd, propStatus, canUpdate, effectiveValue, }) => {
|
|
19
|
+
const TimelineFieldValue = ({ field, onSave, onDragValueChange, onDragEnd, propStatus, canUpdate, effectiveValue, codeValue, }) => {
|
|
77
20
|
const wrapperStyle = canUpdate === null || canUpdate === false
|
|
78
21
|
? notEditableBackground
|
|
79
22
|
: undefined;
|
|
@@ -81,24 +24,26 @@ const TimelineFieldValue = ({ field, onSave, onDragValueChange, onDragEnd, propS
|
|
|
81
24
|
return jsx_runtime_1.jsx("span", { style: unsupportedLabel, children: "unsupported" });
|
|
82
25
|
}
|
|
83
26
|
if (propStatus !== null && !propStatus.canUpdate) {
|
|
84
|
-
|
|
27
|
+
if (propStatus.reason === 'computed') {
|
|
28
|
+
return jsx_runtime_1.jsx("span", { style: unsupportedLabel, children: "computed" });
|
|
29
|
+
}
|
|
30
|
+
throw new Error(`Unsupported prop status: ${propStatus.reason}`);
|
|
85
31
|
}
|
|
86
32
|
if (propStatus === null) {
|
|
87
|
-
return (jsx_runtime_1.jsx("span", { style:
|
|
33
|
+
return (jsx_runtime_1.jsx("span", { style: notEditableBackground, children: jsx_runtime_1.jsx("span", { style: unsupportedLabel, children: "error" }) }));
|
|
88
34
|
}
|
|
89
35
|
if (field.typeName === 'number') {
|
|
90
|
-
return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineNumberField, { field: field,
|
|
36
|
+
return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineNumberField_1.TimelineNumberField, { field: field, effectiveValue: effectiveValue, canUpdate: canUpdate, onSave: onSave, codeValue: codeValue, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd }) }));
|
|
37
|
+
}
|
|
38
|
+
if (field.typeName === 'rotation') {
|
|
39
|
+
return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineRotationField_1.TimelineRotationField, { field: field, effectiveValue: effectiveValue, codeValue: codeValue, canUpdate: canUpdate, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd }) }));
|
|
40
|
+
}
|
|
41
|
+
if (field.typeName === 'translate') {
|
|
42
|
+
return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineTranslateField_1.TimelineTranslateField, { field: field, effectiveValue: effectiveValue, codeValue: codeValue, canUpdate: canUpdate, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd }) }));
|
|
91
43
|
}
|
|
92
44
|
if (field.typeName === 'boolean') {
|
|
93
|
-
return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineBooleanField, { field: field, codeValue:
|
|
45
|
+
return (jsx_runtime_1.jsx("span", { style: wrapperStyle, children: jsx_runtime_1.jsx(TimelineBooleanField_1.TimelineBooleanField, { field: field, codeValue: codeValue, canUpdate: canUpdate, onSave: onSave, effectiveValue: effectiveValue }) }));
|
|
94
46
|
}
|
|
95
47
|
return (jsx_runtime_1.jsx("span", { style: { ...unsupportedLabel, fontStyle: 'normal' }, children: String(effectiveValue) }));
|
|
96
48
|
};
|
|
97
49
|
exports.TimelineFieldValue = TimelineFieldValue;
|
|
98
|
-
const TimelineFieldSavingSpinner = ({ saving }) => {
|
|
99
|
-
if (!saving) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
return jsx_runtime_1.jsx(Spinner_1.Spinner, { duration: 0.5, size: 12 });
|
|
103
|
-
};
|
|
104
|
-
exports.TimelineFieldSavingSpinner = TimelineFieldSavingSpinner;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SchemaFieldInfo } from '../../helpers/timeline-layout';
|
|
3
|
+
export declare const TimelineTranslateField: React.FC<{
|
|
4
|
+
readonly field: SchemaFieldInfo;
|
|
5
|
+
readonly codeValue: unknown;
|
|
6
|
+
readonly effectiveValue: unknown;
|
|
7
|
+
readonly canUpdate: boolean;
|
|
8
|
+
readonly onSave: (key: string, value: unknown) => Promise<void>;
|
|
9
|
+
readonly onDragValueChange: (key: string, value: unknown) => void;
|
|
10
|
+
readonly onDragEnd: () => void;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineTranslateField = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const InputDragger_1 = require("../NewComposition/InputDragger");
|
|
7
|
+
const timeline_field_utils_1 = require("./timeline-field-utils");
|
|
8
|
+
const leftDraggerStyle = {
|
|
9
|
+
paddingLeft: 0,
|
|
10
|
+
};
|
|
11
|
+
const rightDraggerStyle = {
|
|
12
|
+
paddingRight: 0,
|
|
13
|
+
};
|
|
14
|
+
const PIXEL_PATTERN = /^(-?\d+(?:\.\d+)?)px(?:\s+(-?\d+(?:\.\d+)?)px)?$/;
|
|
15
|
+
const parseTranslate = (value) => {
|
|
16
|
+
const m = value.match(PIXEL_PATTERN);
|
|
17
|
+
if (!m) {
|
|
18
|
+
return [0, 0];
|
|
19
|
+
}
|
|
20
|
+
return [Number(m[1]), m[2] !== undefined ? Number(m[2]) : 0];
|
|
21
|
+
};
|
|
22
|
+
const containerStyle = {
|
|
23
|
+
display: 'flex',
|
|
24
|
+
gap: 4,
|
|
25
|
+
};
|
|
26
|
+
const TimelineTranslateField = ({ field, codeValue, effectiveValue, canUpdate, onSave, onDragValueChange, onDragEnd, }) => {
|
|
27
|
+
var _a;
|
|
28
|
+
const [dragX, setDragX] = (0, react_1.useState)(null);
|
|
29
|
+
const [dragY, setDragY] = (0, react_1.useState)(null);
|
|
30
|
+
const [codeX, codeY] = (0, react_1.useMemo)(() => parseTranslate(String(effectiveValue !== null && effectiveValue !== void 0 ? effectiveValue : '0px 0px')), [effectiveValue]);
|
|
31
|
+
const makeString = (0, react_1.useCallback)((x, y) => `${x}px ${y}px`, []);
|
|
32
|
+
(0, react_1.useEffect)(() => {
|
|
33
|
+
setDragX(null);
|
|
34
|
+
setDragY(null);
|
|
35
|
+
onDragEnd();
|
|
36
|
+
}, [field.currentValue, onDragEnd]);
|
|
37
|
+
const step = field.fieldSchema.type === 'translate' ? ((_a = field.fieldSchema.step) !== null && _a !== void 0 ? _a : 1) : 1;
|
|
38
|
+
const stepDecimals = (0, react_1.useMemo)(() => (0, timeline_field_utils_1.getDecimalPlaces)(step), [step]);
|
|
39
|
+
const formatter = (0, react_1.useCallback)((v) => {
|
|
40
|
+
const num = Number(v);
|
|
41
|
+
const digits = Math.max(stepDecimals, (0, timeline_field_utils_1.getDecimalPlaces)(num));
|
|
42
|
+
const formatted = digits === 0 ? String(num) : num.toFixed(digits);
|
|
43
|
+
return `${formatted}px`;
|
|
44
|
+
}, [stepDecimals]);
|
|
45
|
+
// --- X callbacks ---
|
|
46
|
+
const onXChange = (0, react_1.useCallback)((newVal) => {
|
|
47
|
+
setDragX(newVal);
|
|
48
|
+
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
|
|
49
|
+
onDragValueChange(field.key, makeString(newVal, currentY));
|
|
50
|
+
}, [onDragValueChange, field.key, dragY, codeY, makeString]);
|
|
51
|
+
const onXChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
52
|
+
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
|
|
53
|
+
const newStr = makeString(newVal, currentY);
|
|
54
|
+
if (canUpdate && newStr !== codeValue) {
|
|
55
|
+
onSave(field.key, newStr).catch(() => {
|
|
56
|
+
setDragX(null);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
setDragX(null);
|
|
61
|
+
}
|
|
62
|
+
}, [canUpdate, onSave, field.key, codeValue, dragY, codeY, makeString]);
|
|
63
|
+
const onXTextChange = (0, react_1.useCallback)((newVal) => {
|
|
64
|
+
if (canUpdate) {
|
|
65
|
+
const parsed = Number(newVal);
|
|
66
|
+
if (!Number.isNaN(parsed)) {
|
|
67
|
+
const currentY = dragY !== null && dragY !== void 0 ? dragY : codeY;
|
|
68
|
+
const newStr = makeString(parsed, currentY);
|
|
69
|
+
if (newStr !== codeValue) {
|
|
70
|
+
setDragX(parsed);
|
|
71
|
+
onSave(field.key, newStr).catch(() => {
|
|
72
|
+
setDragX(null);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, [canUpdate, onSave, field.key, codeValue, dragY, codeY, makeString]);
|
|
78
|
+
// --- Y callbacks ---
|
|
79
|
+
const onYChange = (0, react_1.useCallback)((newVal) => {
|
|
80
|
+
setDragY(newVal);
|
|
81
|
+
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
|
|
82
|
+
onDragValueChange(field.key, makeString(currentX, newVal));
|
|
83
|
+
}, [onDragValueChange, field.key, dragX, codeX, makeString]);
|
|
84
|
+
const onYChangeEnd = (0, react_1.useCallback)((newVal) => {
|
|
85
|
+
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
|
|
86
|
+
const newStr = makeString(currentX, newVal);
|
|
87
|
+
if (canUpdate && newStr !== codeValue) {
|
|
88
|
+
onSave(field.key, newStr).catch(() => {
|
|
89
|
+
setDragY(null);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
setDragY(null);
|
|
94
|
+
}
|
|
95
|
+
}, [canUpdate, onSave, field.key, codeValue, dragX, codeX, makeString]);
|
|
96
|
+
const onYTextChange = (0, react_1.useCallback)((newVal) => {
|
|
97
|
+
if (canUpdate) {
|
|
98
|
+
const parsed = Number(newVal);
|
|
99
|
+
if (!Number.isNaN(parsed)) {
|
|
100
|
+
const currentX = dragX !== null && dragX !== void 0 ? dragX : codeX;
|
|
101
|
+
const newStr = makeString(currentX, parsed);
|
|
102
|
+
if (newStr !== codeValue) {
|
|
103
|
+
setDragY(parsed);
|
|
104
|
+
onSave(field.key, newStr).catch(() => {
|
|
105
|
+
setDragY(null);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}, [canUpdate, onSave, field.key, codeValue, dragX, codeX, makeString]);
|
|
111
|
+
return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
|
|
112
|
+
jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragX !== null && dragX !== void 0 ? dragX : codeX, style: leftDraggerStyle, status: "ok", small: true, onValueChange: onXChange, onValueChangeEnd: onXChangeEnd, onTextChange: onXTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false }), jsx_runtime_1.jsx("div", { style: { marginLeft: -6, marginRight: -6 } }), jsx_runtime_1.jsx(InputDragger_1.InputDragger, { type: "number", value: dragY !== null && dragY !== void 0 ? dragY : codeY, style: rightDraggerStyle, status: "ok", small: true, onValueChange: onYChange, onValueChangeEnd: onYChangeEnd, onTextChange: onYTextChange, min: -Infinity, max: Infinity, step: step, formatter: formatter, rightAlign: false })
|
|
113
|
+
] }));
|
|
114
|
+
};
|
|
115
|
+
exports.TimelineTranslateField = TimelineTranslateField;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.draggerStyle = exports.getDecimalPlaces = void 0;
|
|
4
|
+
const getDecimalPlaces = (num) => {
|
|
5
|
+
const str = String(num);
|
|
6
|
+
const decimalIndex = str.indexOf('.');
|
|
7
|
+
return decimalIndex === -1 ? 0 : str.length - decimalIndex - 1;
|
|
8
|
+
};
|
|
9
|
+
exports.getDecimalPlaces = getDecimalPlaces;
|
|
10
|
+
exports.draggerStyle = {
|
|
11
|
+
width: 80,
|
|
12
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SequenceNodePath } from '@remotion/studio-shared';
|
|
1
2
|
import type { TSequence } from 'remotion';
|
|
2
3
|
import type { OriginalPosition } from '../../error-overlay/react-overlay/utils/get-source-map';
|
|
3
|
-
export declare const useSequencePropsSubscription: (sequence: TSequence, originalLocation: OriginalPosition | null) =>
|
|
4
|
+
export declare const useSequencePropsSubscription: (sequence: TSequence, originalLocation: OriginalPosition | null) => SequenceNodePath | null;
|