@remotion/studio 4.0.461 → 4.0.463
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/components/AssetSelector.js +2 -6
- package/dist/components/CompSelectorRef.js +2 -6
- package/dist/components/ExpandedTracksProvider.js +13 -23
- package/dist/components/Timeline/SubscribeToNodePaths.d.ts +4 -3
- package/dist/components/Timeline/SubscribeToNodePaths.js +6 -1
- package/dist/components/Timeline/Timeline.js +1 -1
- package/dist/components/Timeline/TimelineColorField.d.ts +11 -0
- package/dist/components/Timeline/TimelineColorField.js +181 -0
- package/dist/components/Timeline/TimelineEffectFieldRow.d.ts +11 -0
- package/dist/components/Timeline/TimelineEffectFieldRow.js +167 -0
- package/dist/components/Timeline/TimelineEffectGroupRow.d.ts +17 -0
- package/dist/components/Timeline/TimelineEffectGroupRow.js +73 -0
- package/dist/components/Timeline/TimelineExpandedRow.d.ts +3 -3
- package/dist/components/Timeline/TimelineExpandedRow.js +12 -1
- package/dist/components/Timeline/TimelineExpandedSection.d.ts +2 -2
- package/dist/components/Timeline/TimelineExpandedSection.js +7 -20
- package/dist/components/Timeline/TimelineFieldRow.d.ts +3 -3
- package/dist/components/Timeline/TimelineFieldRow.js +17 -45
- package/dist/components/Timeline/TimelineLayerEye.d.ts +5 -3
- package/dist/components/Timeline/TimelineLayerEye.js +18 -1
- package/dist/components/Timeline/TimelineListItem.js +61 -17
- package/dist/components/Timeline/TimelineNumberField.js +1 -1
- package/dist/components/Timeline/TimelineRotationField.js +1 -1
- package/dist/components/Timeline/TimelineSchemaField.d.ts +8 -2
- package/dist/components/Timeline/TimelineSchemaField.js +20 -11
- package/dist/components/Timeline/TimelineTracks.js +4 -4
- package/dist/components/Timeline/TimelineTranslateField.js +4 -2
- package/dist/components/Timeline/save-effect-prop.d.ts +12 -0
- package/dist/components/Timeline/save-effect-prop.js +42 -0
- package/dist/components/Timeline/save-prop-queue.d.ts +12 -0
- package/dist/components/Timeline/save-prop-queue.js +63 -0
- package/dist/components/Timeline/save-sequence-prop.d.ts +11 -0
- package/dist/components/Timeline/save-sequence-prop.js +38 -0
- package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
- package/dist/components/Timeline/sequence-props-subscription-store.js +10 -4
- package/dist/components/Timeline/use-sequence-props-subscription.d.ts +2 -1
- package/dist/components/Timeline/use-sequence-props-subscription.js +3 -1
- package/dist/components/Timeline/use-timeline-height.js +3 -3
- package/dist/esm/chunk-5gtx3pza.js +9 -0
- package/dist/esm/{chunk-yzh34sp0.js → chunk-b0m62frw.js} +4511 -3740
- package/dist/esm/index.mjs +20 -24
- package/dist/esm/internals.mjs +4509 -3753
- package/dist/esm/previewEntry.mjs +3190 -2445
- package/dist/esm/renderEntry.mjs +3 -4
- package/dist/helpers/calculate-timeline.js +13 -5
- package/dist/helpers/get-timeline-sequence-sort-key.d.ts +3 -2
- package/dist/helpers/persist-boolean-map.d.ts +5 -0
- package/dist/helpers/persist-boolean-map.js +56 -0
- package/dist/helpers/persist-open-folders.d.ts +4 -3
- package/dist/helpers/persist-open-folders.js +4 -7
- package/dist/helpers/timeline-layout.d.ts +13 -13
- package/dist/helpers/timeline-layout.js +23 -35
- package/dist/icons/eyedropper.d.ts +4 -0
- package/dist/icons/eyedropper.js +6 -0
- package/package.json +11 -12
- package/dist/esm/chunk-6jf1natv.js +0 -25
|
@@ -11,6 +11,7 @@ const write_static_file_1 = require("../api/write-static-file");
|
|
|
11
11
|
const client_id_1 = require("../helpers/client-id");
|
|
12
12
|
const colors_1 = require("../helpers/colors");
|
|
13
13
|
const create_folder_tree_1 = require("../helpers/create-folder-tree");
|
|
14
|
+
const persist_boolean_map_1 = require("../helpers/persist-boolean-map");
|
|
14
15
|
const persist_open_folders_1 = require("../helpers/persist-open-folders");
|
|
15
16
|
const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
|
|
16
17
|
const folders_1 = require("../state/folders");
|
|
@@ -68,13 +69,8 @@ const AssetSelector = ({ readOnlyStudio }) => {
|
|
|
68
69
|
}, [assetFoldersExpanded, staticFiles]);
|
|
69
70
|
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
|
|
70
71
|
setAssetFoldersExpanded((p) => {
|
|
71
|
-
var _a;
|
|
72
72
|
const key = [parentName, folderName].filter(Boolean).join('/');
|
|
73
|
-
const
|
|
74
|
-
const foldersExpandedState = {
|
|
75
|
-
...p,
|
|
76
|
-
[key]: !prev,
|
|
77
|
-
};
|
|
73
|
+
const foldersExpandedState = (0, persist_boolean_map_1.toggleBooleanMapKey)(p, key);
|
|
78
74
|
(0, persist_open_folders_1.persistExpandedFolders)('assets', foldersExpandedState);
|
|
79
75
|
return foldersExpandedState;
|
|
80
76
|
});
|
|
@@ -5,6 +5,7 @@ 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 create_folder_tree_1 = require("../helpers/create-folder-tree");
|
|
8
|
+
const persist_boolean_map_1 = require("../helpers/persist-boolean-map");
|
|
8
9
|
const persist_open_folders_1 = require("../helpers/persist-open-folders");
|
|
9
10
|
const folders_1 = require("../state/folders");
|
|
10
11
|
const InitialCompositionLoader_1 = require("./InitialCompositionLoader");
|
|
@@ -14,13 +15,8 @@ const CompSelectorRef = ({ children }) => {
|
|
|
14
15
|
const selectComposition = (0, InitialCompositionLoader_1.useSelectComposition)();
|
|
15
16
|
const toggleFolder = (0, react_1.useCallback)((folderName, parentName) => {
|
|
16
17
|
setCompositionFoldersExpanded((p) => {
|
|
17
|
-
var _a;
|
|
18
18
|
const key = (0, persist_open_folders_1.openFolderKey)({ folderName, parentName });
|
|
19
|
-
const
|
|
20
|
-
const foldersExpandedState = {
|
|
21
|
-
...p,
|
|
22
|
-
[key]: !prev,
|
|
23
|
-
};
|
|
19
|
+
const foldersExpandedState = (0, persist_boolean_map_1.toggleBooleanMapKey)(p, key);
|
|
24
20
|
(0, persist_open_folders_1.persistExpandedFolders)('compositions', foldersExpandedState);
|
|
25
21
|
return foldersExpandedState;
|
|
26
22
|
});
|
|
@@ -2,27 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ExpandedTracksProvider = exports.ExpandedTracksSetterContext = exports.ExpandedTracksGetterContext = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const studio_shared_1 = require("@remotion/studio-shared");
|
|
5
6
|
const react_1 = require("react");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
7
|
+
const persist_boolean_map_1 = require("../helpers/persist-boolean-map");
|
|
8
|
+
const nodePathInfoToExpandedKey = (info) => [
|
|
9
|
+
(0, studio_shared_1.stringifySequenceExpandedRowKey)(info.sequenceSubscriptionKey),
|
|
10
|
+
info.auxiliaryKeys.join('.'),
|
|
11
|
+
info.index,
|
|
12
|
+
].join('.');
|
|
13
|
+
const SESSION_STORAGE_KEY = 'remotion.editor.expandedTracks';
|
|
8
14
|
const loadExpandedTracks = () => {
|
|
9
|
-
|
|
10
|
-
return {};
|
|
11
|
-
}
|
|
12
|
-
const item = window.localStorage.getItem(LOCAL_STORAGE_KEY);
|
|
13
|
-
if (item === null) {
|
|
14
|
-
return {};
|
|
15
|
-
}
|
|
16
|
-
try {
|
|
17
|
-
const parsed = JSON.parse(item);
|
|
18
|
-
if (parsed && typeof parsed === 'object') {
|
|
19
|
-
return parsed;
|
|
20
|
-
}
|
|
21
|
-
return {};
|
|
22
|
-
}
|
|
23
|
-
catch (_a) {
|
|
24
|
-
return {};
|
|
25
|
-
}
|
|
15
|
+
return (0, persist_boolean_map_1.loadPersistedBooleanMap)(SESSION_STORAGE_KEY);
|
|
26
16
|
};
|
|
27
17
|
exports.ExpandedTracksGetterContext = (0, react_1.createContext)({
|
|
28
18
|
getIsExpanded: () => {
|
|
@@ -38,16 +28,16 @@ const ExpandedTracksProvider = ({ children }) => {
|
|
|
38
28
|
const [expandedTracks, setExpandedTracks] = (0, react_1.useState)(loadExpandedTracks);
|
|
39
29
|
const toggleTrack = (0, react_1.useCallback)((nodePathInfo) => {
|
|
40
30
|
setExpandedTracks((prev) => {
|
|
41
|
-
const key =
|
|
42
|
-
const next =
|
|
43
|
-
|
|
31
|
+
const key = nodePathInfoToExpandedKey(nodePathInfo);
|
|
32
|
+
const next = (0, persist_boolean_map_1.toggleBooleanMapKey)(prev, key);
|
|
33
|
+
(0, persist_boolean_map_1.persistBooleanMap)(SESSION_STORAGE_KEY, next);
|
|
44
34
|
return next;
|
|
45
35
|
});
|
|
46
36
|
}, []);
|
|
47
37
|
const getterValue = (0, react_1.useMemo)(() => ({
|
|
48
38
|
getIsExpanded: (nodePathInfo) => {
|
|
49
39
|
var _a;
|
|
50
|
-
return (_a = expandedTracks[
|
|
40
|
+
return (_a = expandedTracks[nodePathInfoToExpandedKey(nodePathInfo)]) !== null && _a !== void 0 ? _a : false;
|
|
51
41
|
},
|
|
52
42
|
}), [expandedTracks]);
|
|
53
43
|
const setterValue = (0, react_1.useMemo)(() => ({ toggleTrack }), [toggleTrack]);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { SequenceSchema } from 'remotion';
|
|
3
|
-
export declare const SubscribeToNodePaths:
|
|
1
|
+
import { type FC } from 'react';
|
|
2
|
+
import type { EffectDefinition, SequenceSchema } from 'remotion';
|
|
3
|
+
export declare const SubscribeToNodePaths: FC<{
|
|
4
4
|
readonly overrideId: string;
|
|
5
5
|
readonly schema: SequenceSchema;
|
|
6
6
|
readonly stack: string;
|
|
7
|
+
readonly effects: readonly EffectDefinition<unknown>[];
|
|
7
8
|
}>;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SubscribeToNodePaths = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
4
5
|
const use_resolved_stack_1 = require("./use-resolved-stack");
|
|
5
6
|
const use_sequence_props_subscription_1 = require("./use-sequence-props-subscription");
|
|
6
|
-
const SubscribeToNodePaths = ({ overrideId, schema, stack }) => {
|
|
7
|
+
const SubscribeToNodePaths = ({ overrideId, schema, stack, effects }) => {
|
|
7
8
|
const originalLocation = (0, use_resolved_stack_1.useResolvedStack)(stack);
|
|
9
|
+
const effectSubscriptions = (0, react_1.useMemo)(() => {
|
|
10
|
+
return effects.map((effect) => effect.schema);
|
|
11
|
+
}, [effects]);
|
|
8
12
|
(0, use_sequence_props_subscription_1.useSequencePropsSubscription)({
|
|
9
13
|
overrideId,
|
|
10
14
|
schema,
|
|
15
|
+
effects: effectSubscriptions,
|
|
11
16
|
originalLocation,
|
|
12
17
|
});
|
|
13
18
|
return null;
|
|
@@ -103,7 +103,7 @@ const TimelineInner = () => {
|
|
|
103
103
|
if (!sequence.controls || !previewConnected || !sequence.stack) {
|
|
104
104
|
return null;
|
|
105
105
|
}
|
|
106
|
-
return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, schema: sequence.controls.schema, stack: sequence.stack }, sequence.id));
|
|
106
|
+
return (jsx_runtime_1.jsx(SubscribeToNodePaths_1.SubscribeToNodePaths, { overrideId: sequence.controls.overrideId, schema: sequence.controls.schema, stack: sequence.stack, effects: sequence.effects }, sequence.id));
|
|
107
107
|
}), jsx_runtime_1.jsx(SequencePropsObserver_1.SequencePropsObserver, {}), jsx_runtime_1.jsxs(TimelineWidthProvider_1.TimelineWidthProvider, { children: [
|
|
108
108
|
jsx_runtime_1.jsx(TimelinePinchZoom_1.TimelinePinchZoom, {}), jsx_runtime_1.jsx(TimelineHeightContainer_1.TimelineHeightContainer, { shown: shown, hasBeenCut: hasBeenCut, children: jsx_runtime_1.jsxs(SplitterContainer_1.SplitterContainer, { orientation: "vertical", defaultFlex: 0.2, id: "names-to-timeline", maxFlex: 0.5, minFlex: 0.15, children: [
|
|
109
109
|
jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "flexer", sticky: jsx_runtime_1.jsx(TimelineTimeIndicators_1.TimelineTimePlaceholders, {}), children: jsx_runtime_1.jsx(TimelineList_1.TimelineList, { timeline: shown }) }), jsx_runtime_1.jsx(SplitterHandle_1.SplitterHandle, { onCollapse: noop, allowToCollapse: "none" }), jsx_runtime_1.jsx(SplitterElement_1.SplitterElement, { type: "anti-flexer", sticky: null, children: jsx_runtime_1.jsxs(TimelineScrollable_1.TimelineScrollable, { children: [
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CanUpdateSequencePropStatus } from 'remotion';
|
|
3
|
+
import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSave } from '../../helpers/timeline-layout';
|
|
4
|
+
export declare const TimelineColorField: React.FC<{
|
|
5
|
+
readonly field: SchemaFieldInfo;
|
|
6
|
+
readonly effectiveValue: unknown;
|
|
7
|
+
readonly propStatus: CanUpdateSequencePropStatus;
|
|
8
|
+
readonly onSave: TimelineFieldOnSave;
|
|
9
|
+
readonly onDragValueChange: TimelineFieldOnDragValueChange;
|
|
10
|
+
readonly onDragEnd: () => void;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineColorField = 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 eyedropper_1 = require("../../icons/eyedropper");
|
|
9
|
+
const z_index_1 = require("../../state/z-index");
|
|
10
|
+
const SWATCH_WIDTH = 20;
|
|
11
|
+
const SWATCH_HEIGHT = 15;
|
|
12
|
+
const containerStyle = {
|
|
13
|
+
display: 'flex',
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
gap: 3,
|
|
16
|
+
};
|
|
17
|
+
const swatchWrapperBase = {
|
|
18
|
+
position: 'relative',
|
|
19
|
+
width: SWATCH_WIDTH,
|
|
20
|
+
height: SWATCH_HEIGHT,
|
|
21
|
+
display: 'inline-block',
|
|
22
|
+
borderRadius: 3,
|
|
23
|
+
overflow: 'hidden',
|
|
24
|
+
cursor: 'pointer',
|
|
25
|
+
borderStyle: 'solid',
|
|
26
|
+
borderWidth: 1,
|
|
27
|
+
};
|
|
28
|
+
const hiddenInputStyle = {
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
inset: 0,
|
|
31
|
+
width: '100%',
|
|
32
|
+
height: '100%',
|
|
33
|
+
opacity: 0,
|
|
34
|
+
cursor: 'pointer',
|
|
35
|
+
border: 'none',
|
|
36
|
+
padding: 0,
|
|
37
|
+
margin: 0,
|
|
38
|
+
};
|
|
39
|
+
const swatchFillStyle = {
|
|
40
|
+
width: '100%',
|
|
41
|
+
height: '100%',
|
|
42
|
+
};
|
|
43
|
+
const eyedropperButtonBase = {
|
|
44
|
+
background: 'transparent',
|
|
45
|
+
border: 'none',
|
|
46
|
+
padding: 0,
|
|
47
|
+
margin: 0,
|
|
48
|
+
cursor: 'pointer',
|
|
49
|
+
display: 'inline-flex',
|
|
50
|
+
alignItems: 'center',
|
|
51
|
+
justifyContent: 'center',
|
|
52
|
+
width: 20,
|
|
53
|
+
height: 20,
|
|
54
|
+
color: 'rgba(255, 255, 255, 0.7)',
|
|
55
|
+
};
|
|
56
|
+
const eyedropperIconStyle = {
|
|
57
|
+
width: 16,
|
|
58
|
+
height: 16,
|
|
59
|
+
};
|
|
60
|
+
// Normalizes any color string the user provided (e.g. `red`, `rgb(...)`, `#fff`)
|
|
61
|
+
// into a `#rrggbb` string that `<input type="color">` accepts.
|
|
62
|
+
const toHex = (value) => {
|
|
63
|
+
try {
|
|
64
|
+
const argb = no_react_1.NoReactInternals.processColor(value);
|
|
65
|
+
const r = (argb >>> 16) & 0xff;
|
|
66
|
+
const g = (argb >>> 8) & 0xff;
|
|
67
|
+
const b = argb & 0xff;
|
|
68
|
+
return `#${r.toString(16).padStart(2, '0')}${g
|
|
69
|
+
.toString(16)
|
|
70
|
+
.padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
71
|
+
}
|
|
72
|
+
catch (_a) {
|
|
73
|
+
return '#000000';
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const hasEyeDropper = () => typeof window !== 'undefined' && 'EyeDropper' in window;
|
|
77
|
+
const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragValueChange, onDragEnd, }) => {
|
|
78
|
+
const inputRef = (0, react_1.useRef)(null);
|
|
79
|
+
const [isHovered, setIsHovered] = (0, react_1.useState)(false);
|
|
80
|
+
const [isFocused, setIsFocused] = (0, react_1.useState)(false);
|
|
81
|
+
const { tabIndex } = (0, z_index_1.useZIndex)();
|
|
82
|
+
const commitTimeoutRef = (0, react_1.useRef)(null);
|
|
83
|
+
const pendingCommitRef = (0, react_1.useRef)(null);
|
|
84
|
+
// `<input type="color">` doesn't fire an event when dismissed; debounce
|
|
85
|
+
// commits and flush any pending commit on unmount so we never lose the
|
|
86
|
+
// final value.
|
|
87
|
+
(0, react_1.useEffect)(() => {
|
|
88
|
+
return () => {
|
|
89
|
+
if (commitTimeoutRef.current) {
|
|
90
|
+
clearTimeout(commitTimeoutRef.current);
|
|
91
|
+
}
|
|
92
|
+
if (pendingCommitRef.current) {
|
|
93
|
+
pendingCommitRef.current();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}, []);
|
|
97
|
+
const currentValue = typeof effectiveValue === 'string'
|
|
98
|
+
? effectiveValue
|
|
99
|
+
: field.fieldSchema.type === 'color'
|
|
100
|
+
? field.fieldSchema.default
|
|
101
|
+
: '';
|
|
102
|
+
const hexValue = (0, react_1.useMemo)(() => toHex(currentValue), [currentValue]);
|
|
103
|
+
const onColorChange = (0, react_1.useCallback)((e) => {
|
|
104
|
+
const newValue = e.target.value;
|
|
105
|
+
if (!propStatus.canUpdate) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
onDragValueChange(newValue);
|
|
109
|
+
if (commitTimeoutRef.current) {
|
|
110
|
+
clearTimeout(commitTimeoutRef.current);
|
|
111
|
+
}
|
|
112
|
+
const commit = () => {
|
|
113
|
+
pendingCommitRef.current = null;
|
|
114
|
+
if (propStatus.canUpdate && newValue !== propStatus.codeValue) {
|
|
115
|
+
onSave(newValue);
|
|
116
|
+
}
|
|
117
|
+
onDragEnd();
|
|
118
|
+
};
|
|
119
|
+
pendingCommitRef.current = commit;
|
|
120
|
+
commitTimeoutRef.current = setTimeout(() => {
|
|
121
|
+
commitTimeoutRef.current = null;
|
|
122
|
+
commit();
|
|
123
|
+
}, 500);
|
|
124
|
+
}, [onSave, onDragValueChange, onDragEnd, propStatus]);
|
|
125
|
+
const onPickColor = (0, react_1.useCallback)(() => {
|
|
126
|
+
// `EyeDropper` is a Chromium-only API; it's feature-detected at render
|
|
127
|
+
// time so this only runs in supported browsers.
|
|
128
|
+
const EyeDropperCtor = typeof window !== 'undefined'
|
|
129
|
+
? window.EyeDropper
|
|
130
|
+
: undefined;
|
|
131
|
+
if (!EyeDropperCtor) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const eyeDropper = new EyeDropperCtor();
|
|
135
|
+
eyeDropper
|
|
136
|
+
.open()
|
|
137
|
+
.then((result) => {
|
|
138
|
+
if (propStatus.canUpdate && result.sRGBHex !== propStatus.codeValue) {
|
|
139
|
+
onSave(result.sRGBHex);
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
.catch(() => {
|
|
143
|
+
// User aborted or picker failed; safe to ignore.
|
|
144
|
+
});
|
|
145
|
+
}, [onSave, propStatus]);
|
|
146
|
+
const swatchWrapperStyle = (0, react_1.useMemo)(() => {
|
|
147
|
+
return {
|
|
148
|
+
...swatchWrapperBase,
|
|
149
|
+
borderColor: isHovered || isFocused
|
|
150
|
+
? colors_1.INPUT_BORDER_COLOR_HOVERED
|
|
151
|
+
: colors_1.INPUT_BORDER_COLOR_UNHOVERED,
|
|
152
|
+
cursor: propStatus.canUpdate ? 'pointer' : 'not-allowed',
|
|
153
|
+
marginLeft: 5,
|
|
154
|
+
};
|
|
155
|
+
}, [isFocused, isHovered, propStatus.canUpdate]);
|
|
156
|
+
const swatchFill = (0, react_1.useMemo)(() => {
|
|
157
|
+
return {
|
|
158
|
+
...swatchFillStyle,
|
|
159
|
+
backgroundColor: currentValue || hexValue,
|
|
160
|
+
position: 'absolute',
|
|
161
|
+
display: 'block',
|
|
162
|
+
};
|
|
163
|
+
}, [currentValue, hexValue]);
|
|
164
|
+
const onMouseEnter = (0, react_1.useCallback)(() => setIsHovered(true), []);
|
|
165
|
+
const onMouseLeave = (0, react_1.useCallback)(() => setIsHovered(false), []);
|
|
166
|
+
const onFocus = (0, react_1.useCallback)(() => setIsFocused(true), []);
|
|
167
|
+
const onBlur = (0, react_1.useCallback)(() => setIsFocused(false), []);
|
|
168
|
+
const onSwatchClick = (0, react_1.useCallback)(() => {
|
|
169
|
+
var _a;
|
|
170
|
+
if (!propStatus.canUpdate) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
174
|
+
}, [propStatus.canUpdate]);
|
|
175
|
+
const showEyeDropper = hasEyeDropper();
|
|
176
|
+
return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
|
|
177
|
+
jsx_runtime_1.jsxs("span", { style: swatchWrapperStyle, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onSwatchClick, title: currentValue, children: [
|
|
178
|
+
jsx_runtime_1.jsx("span", { style: swatchFill }), jsx_runtime_1.jsx("input", { ref: inputRef, type: "color", value: hexValue, onChange: onColorChange, onFocus: onFocus, onBlur: onBlur, disabled: !propStatus.canUpdate, name: field.key, tabIndex: tabIndex, style: hiddenInputStyle })
|
|
179
|
+
] }), showEyeDropper ? (jsx_runtime_1.jsx("button", { type: "button", onClick: onPickColor, disabled: !propStatus.canUpdate, style: eyedropperButtonBase, tabIndex: tabIndex, title: "Pick color from screen", "aria-label": "Pick color from screen", children: jsx_runtime_1.jsx(eyedropper_1.EyedropperIcon, { style: eyedropperIconStyle, color: "rgba(255, 255, 255, 0.7)" }) })) : null] }));
|
|
180
|
+
};
|
|
181
|
+
exports.TimelineColorField = TimelineColorField;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SequencePropsSubscriptionKey } from 'remotion';
|
|
3
|
+
import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
|
|
4
|
+
import type { EffectSchemaFieldInfo } from '../../helpers/timeline-layout';
|
|
5
|
+
export declare const TimelineEffectFieldRow: React.FC<{
|
|
6
|
+
readonly field: EffectSchemaFieldInfo;
|
|
7
|
+
readonly validatedLocation: CodePosition;
|
|
8
|
+
readonly paddingLeft: number;
|
|
9
|
+
readonly nestedDepth: number;
|
|
10
|
+
readonly nodePath: SequencePropsSubscriptionKey;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineEffectFieldRow = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const studio_shared_1 = require("@remotion/studio-shared");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const remotion_1 = require("remotion");
|
|
8
|
+
const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
9
|
+
const call_api_1 = require("../call-api");
|
|
10
|
+
const Padder_1 = require("./Padder");
|
|
11
|
+
const save_prop_queue_1 = require("./save-prop-queue");
|
|
12
|
+
const TimelineSchemaField_1 = require("./TimelineSchemaField");
|
|
13
|
+
const fieldRowBase = {
|
|
14
|
+
display: 'flex',
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
gap: 8,
|
|
17
|
+
paddingRight: timeline_layout_1.EXPANDED_SECTION_PADDING_RIGHT,
|
|
18
|
+
};
|
|
19
|
+
const fieldName = {
|
|
20
|
+
fontSize: 12,
|
|
21
|
+
color: 'rgba(255, 255, 255, 0.8)',
|
|
22
|
+
userSelect: 'none',
|
|
23
|
+
};
|
|
24
|
+
const fieldLabelRow = {
|
|
25
|
+
flex: '0 0 50%',
|
|
26
|
+
display: 'flex',
|
|
27
|
+
flexDirection: 'row',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
gap: 6,
|
|
30
|
+
};
|
|
31
|
+
const Value = ({ field, nodePath, validatedLocation }) => {
|
|
32
|
+
var _a;
|
|
33
|
+
var _b;
|
|
34
|
+
const { setEffectDragOverrides, clearEffectDragOverrides, setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
35
|
+
const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
36
|
+
const { codeValues: visualModeCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
|
|
37
|
+
const effectStatus = remotion_1.Internals.getEffectCodeValuesCtx({
|
|
38
|
+
codeValues: visualModeCodeValues,
|
|
39
|
+
nodePath,
|
|
40
|
+
effectIndex: field.effectIndex,
|
|
41
|
+
});
|
|
42
|
+
const propStatus = effectStatus.type === 'can-update-effect'
|
|
43
|
+
? ((_b = (_a = effectStatus.props) === null || _a === void 0 ? void 0 : _a[field.key]) !== null && _b !== void 0 ? _b : null)
|
|
44
|
+
: null;
|
|
45
|
+
const onDragValueChange = (0, react_1.useCallback)((value) => {
|
|
46
|
+
setEffectDragOverrides(nodePath, field.effectIndex, field.key, value);
|
|
47
|
+
}, [setEffectDragOverrides, nodePath, field.effectIndex, field.key]);
|
|
48
|
+
const onDragEnd = (0, react_1.useCallback)(() => {
|
|
49
|
+
clearEffectDragOverrides(nodePath, field.effectIndex);
|
|
50
|
+
}, [clearEffectDragOverrides, nodePath, field.effectIndex]);
|
|
51
|
+
const dragOverrideValue = (0, react_1.useMemo)(() => {
|
|
52
|
+
const overrides = getEffectDragOverrides(nodePath, field.effectIndex);
|
|
53
|
+
return overrides[field.key];
|
|
54
|
+
}, [getEffectDragOverrides, nodePath, field.effectIndex, field.key]);
|
|
55
|
+
const onSave = (0, react_1.useCallback)((value) => {
|
|
56
|
+
if (!validatedLocation) {
|
|
57
|
+
return Promise.reject(new Error('Cannot save'));
|
|
58
|
+
}
|
|
59
|
+
if (!propStatus) {
|
|
60
|
+
return Promise.reject(new Error('Cannot save'));
|
|
61
|
+
}
|
|
62
|
+
if (!propStatus.canUpdate) {
|
|
63
|
+
return Promise.reject(new Error('Cannot save'));
|
|
64
|
+
}
|
|
65
|
+
const defaultValue = field.fieldSchema.default !== undefined
|
|
66
|
+
? JSON.stringify(field.fieldSchema.default)
|
|
67
|
+
: null;
|
|
68
|
+
const stringifiedValue = JSON.stringify(value);
|
|
69
|
+
if (value === propStatus.codeValue) {
|
|
70
|
+
return Promise.resolve();
|
|
71
|
+
}
|
|
72
|
+
if (defaultValue === stringifiedValue &&
|
|
73
|
+
propStatus.codeValue === undefined) {
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
}
|
|
76
|
+
return (0, save_prop_queue_1.enqueueSavePropChange)({
|
|
77
|
+
nodePath,
|
|
78
|
+
setCodeValues,
|
|
79
|
+
applyOptimistic: (prev) => (0, studio_shared_1.optimisticUpdateForEffectCodeValues)({
|
|
80
|
+
previous: prev,
|
|
81
|
+
effectIndex: field.effectIndex,
|
|
82
|
+
fieldKey: field.key,
|
|
83
|
+
value,
|
|
84
|
+
schema: field.effectSchema,
|
|
85
|
+
}),
|
|
86
|
+
apiCall: () => (0, call_api_1.callApi)('/api/save-effect-props', {
|
|
87
|
+
fileName: validatedLocation.source,
|
|
88
|
+
sequenceNodePath: nodePath,
|
|
89
|
+
effectIndex: field.effectIndex,
|
|
90
|
+
key: field.key,
|
|
91
|
+
value: stringifiedValue,
|
|
92
|
+
defaultValue,
|
|
93
|
+
schema: field.effectSchema,
|
|
94
|
+
}),
|
|
95
|
+
mergeServerResponse: (prev, data) => {
|
|
96
|
+
if (!prev.canUpdate) {
|
|
97
|
+
return prev;
|
|
98
|
+
}
|
|
99
|
+
const idx = prev.effects.findIndex((e) => e.effectIndex === field.effectIndex);
|
|
100
|
+
if (idx === -1) {
|
|
101
|
+
return {
|
|
102
|
+
...prev,
|
|
103
|
+
effects: [...prev.effects, data],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const nextEffects = [...prev.effects];
|
|
107
|
+
nextEffects[idx] = data;
|
|
108
|
+
return { ...prev, effects: nextEffects };
|
|
109
|
+
},
|
|
110
|
+
errorLabel: 'Could not save effect prop',
|
|
111
|
+
});
|
|
112
|
+
}, [
|
|
113
|
+
field.effectIndex,
|
|
114
|
+
field.effectSchema,
|
|
115
|
+
field.fieldSchema.default,
|
|
116
|
+
field.key,
|
|
117
|
+
nodePath,
|
|
118
|
+
propStatus,
|
|
119
|
+
setCodeValues,
|
|
120
|
+
validatedLocation,
|
|
121
|
+
]);
|
|
122
|
+
if (effectStatus.type === 'cannot-update-effect') {
|
|
123
|
+
if (effectStatus.reason === 'computed') {
|
|
124
|
+
return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "computed" });
|
|
125
|
+
}
|
|
126
|
+
if (effectStatus.reason === 'not-call-expression') {
|
|
127
|
+
return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "not inline" });
|
|
128
|
+
}
|
|
129
|
+
if (effectStatus.reason === 'not-found') {
|
|
130
|
+
return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "not found in code" });
|
|
131
|
+
}
|
|
132
|
+
throw new Error(`Unsupported effect status: ${effectStatus.reason}`);
|
|
133
|
+
}
|
|
134
|
+
if (effectStatus.type === 'cannot-update-sequence') {
|
|
135
|
+
if (effectStatus.reason === 'not-found') {
|
|
136
|
+
return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "not found in code" });
|
|
137
|
+
}
|
|
138
|
+
if (effectStatus.reason === 'error') {
|
|
139
|
+
return jsx_runtime_1.jsx(TimelineSchemaField_1.UnsupportedStatus, { label: "error" });
|
|
140
|
+
}
|
|
141
|
+
throw new Error(`Unsupported effect status: ${effectStatus.reason}`);
|
|
142
|
+
}
|
|
143
|
+
if (propStatus === null || !propStatus.canUpdate) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const effectiveValue = remotion_1.Internals.getEffectiveVisualModeValue({
|
|
147
|
+
codeValue: propStatus,
|
|
148
|
+
dragOverrideValue,
|
|
149
|
+
defaultValue: field.fieldSchema.default,
|
|
150
|
+
shouldResortToDefaultValueIfUndefined: true,
|
|
151
|
+
});
|
|
152
|
+
return (jsx_runtime_1.jsx(TimelineSchemaField_1.TimelineFieldValue, { field: field, propStatus: propStatus, onSave: onSave, onDragValueChange: onDragValueChange, onDragEnd: onDragEnd, effectiveValue: effectiveValue }));
|
|
153
|
+
};
|
|
154
|
+
const TimelineEffectFieldRow = ({ field, validatedLocation, paddingLeft, nestedDepth, nodePath }) => {
|
|
155
|
+
var _a;
|
|
156
|
+
const style = (0, react_1.useMemo)(() => {
|
|
157
|
+
return {
|
|
158
|
+
...fieldRowBase,
|
|
159
|
+
height: field.rowHeight,
|
|
160
|
+
paddingLeft,
|
|
161
|
+
};
|
|
162
|
+
}, [field.rowHeight, paddingLeft]);
|
|
163
|
+
return (jsx_runtime_1.jsxs("div", { style: style, children: [
|
|
164
|
+
jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), jsx_runtime_1.jsx("div", { style: fieldLabelRow, children: jsx_runtime_1.jsx("span", { style: fieldName, children: (_a = field.description) !== null && _a !== void 0 ? _a : field.key }) }), jsx_runtime_1.jsx(Value, { field: field, nodePath: nodePath, validatedLocation: validatedLocation })
|
|
165
|
+
] }));
|
|
166
|
+
};
|
|
167
|
+
exports.TimelineEffectFieldRow = TimelineEffectFieldRow;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
|
|
3
|
+
import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
|
|
4
|
+
import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
|
|
5
|
+
import type { GetIsExpanded } from '../ExpandedTracksProvider';
|
|
6
|
+
export declare const TimelineEffectGroupRow: React.FC<{
|
|
7
|
+
readonly label: string;
|
|
8
|
+
readonly nodePathInfo: SequenceNodePathInfo;
|
|
9
|
+
readonly effectIndex: number;
|
|
10
|
+
readonly effectSchema: SequenceSchema;
|
|
11
|
+
readonly nodePath: SequencePropsSubscriptionKey;
|
|
12
|
+
readonly validatedLocation: CodePosition;
|
|
13
|
+
readonly nestedDepth: number;
|
|
14
|
+
readonly style: React.CSSProperties;
|
|
15
|
+
readonly getIsExpanded: GetIsExpanded;
|
|
16
|
+
readonly toggleTrack: (nodePathInfo: SequenceNodePathInfo) => void;
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimelineEffectGroupRow = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const remotion_1 = require("remotion");
|
|
7
|
+
const Padder_1 = require("./Padder");
|
|
8
|
+
const save_effect_prop_1 = require("./save-effect-prop");
|
|
9
|
+
const TimelineExpandArrowButton_1 = require("./TimelineExpandArrowButton");
|
|
10
|
+
const TimelineLayerEye_1 = require("./TimelineLayerEye");
|
|
11
|
+
const groupRowBase = {
|
|
12
|
+
display: 'flex',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
};
|
|
15
|
+
const rowLabel = {
|
|
16
|
+
fontSize: 12,
|
|
17
|
+
color: 'rgba(255, 255, 255, 0.8)',
|
|
18
|
+
userSelect: 'none',
|
|
19
|
+
};
|
|
20
|
+
const TimelineEffectGroupRow = ({ label, nodePathInfo, effectIndex, effectSchema, nodePath, validatedLocation, nestedDepth, style, getIsExpanded, toggleTrack, }) => {
|
|
21
|
+
var _a;
|
|
22
|
+
var _b;
|
|
23
|
+
const { codeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeCodeValuesContext);
|
|
24
|
+
const { setCodeValues } = (0, react_1.useContext)(remotion_1.Internals.VisualModeSettersContext);
|
|
25
|
+
const effectStatus = (0, react_1.useMemo)(() => remotion_1.Internals.getEffectCodeValuesCtx({
|
|
26
|
+
codeValues,
|
|
27
|
+
nodePath,
|
|
28
|
+
effectIndex,
|
|
29
|
+
}), [codeValues, nodePath, effectIndex]);
|
|
30
|
+
const disabledStatus = effectStatus.type === 'can-update-effect'
|
|
31
|
+
? ((_b = (_a = effectStatus.props) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : null)
|
|
32
|
+
: null;
|
|
33
|
+
const isDisabled = (0, react_1.useMemo)(() => {
|
|
34
|
+
if (disabledStatus && disabledStatus.canUpdate) {
|
|
35
|
+
return Boolean(disabledStatus.codeValue);
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}, [disabledStatus]);
|
|
39
|
+
const canToggle = disabledStatus !== null && disabledStatus.canUpdate;
|
|
40
|
+
const onToggle = (0, react_1.useCallback)((type) => {
|
|
41
|
+
if (!canToggle) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const newValue = type !== 'enable';
|
|
45
|
+
const fieldSchema = effectSchema.disabled;
|
|
46
|
+
const defaultValue = fieldSchema && fieldSchema.type === 'boolean'
|
|
47
|
+
? JSON.stringify(fieldSchema.default)
|
|
48
|
+
: null;
|
|
49
|
+
(0, save_effect_prop_1.saveEffectProp)({
|
|
50
|
+
fileName: validatedLocation.source,
|
|
51
|
+
nodePath,
|
|
52
|
+
effectIndex,
|
|
53
|
+
fieldKey: 'disabled',
|
|
54
|
+
value: newValue,
|
|
55
|
+
defaultValue,
|
|
56
|
+
schema: effectSchema,
|
|
57
|
+
setCodeValues,
|
|
58
|
+
});
|
|
59
|
+
}, [
|
|
60
|
+
canToggle,
|
|
61
|
+
effectIndex,
|
|
62
|
+
effectSchema,
|
|
63
|
+
nodePath,
|
|
64
|
+
setCodeValues,
|
|
65
|
+
validatedLocation.source,
|
|
66
|
+
]);
|
|
67
|
+
const isExpanded = getIsExpanded(nodePathInfo);
|
|
68
|
+
const mergedStyle = (0, react_1.useMemo)(() => ({ ...groupRowBase, ...style }), [style]);
|
|
69
|
+
return (jsx_runtime_1.jsxs("div", { style: mergedStyle, children: [
|
|
70
|
+
jsx_runtime_1.jsx(Padder_1.Padder, { depth: nestedDepth + 1 }), canToggle ? (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEye, { type: "effect", hidden: isDisabled, onInvoked: onToggle })) : (jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {})), jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowButton, { isExpanded: isExpanded, onClick: () => toggleTrack(nodePathInfo), label: `${label} section`, disabled: false }), jsx_runtime_1.jsx("span", { style: rowLabel, children: label })
|
|
71
|
+
] }));
|
|
72
|
+
};
|
|
73
|
+
exports.TimelineEffectGroupRow = TimelineEffectGroupRow;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { SequenceSchema,
|
|
2
|
+
import type { SequenceSchema, SequencePropsSubscriptionKey } from 'remotion';
|
|
3
3
|
import type { CodePosition } from '../../error-overlay/react-overlay/utils/get-source-map';
|
|
4
4
|
import type { SequenceNodePathInfo } from '../../helpers/get-timeline-sequence-sort-key';
|
|
5
5
|
import type { TimelineTreeNode } from '../../helpers/timeline-layout';
|
|
@@ -10,7 +10,7 @@ export declare const TimelineExpandedRow: React.FC<{
|
|
|
10
10
|
readonly nestedDepth: number;
|
|
11
11
|
readonly getIsExpanded: GetIsExpanded;
|
|
12
12
|
readonly toggleTrack: (nodePathInfo: SequenceNodePathInfo) => void;
|
|
13
|
-
readonly validatedLocation: CodePosition
|
|
14
|
-
readonly nodePath:
|
|
13
|
+
readonly validatedLocation: CodePosition;
|
|
14
|
+
readonly nodePath: SequencePropsSubscriptionKey;
|
|
15
15
|
readonly schema: SequenceSchema;
|
|
16
16
|
}>;
|