@remotion/studio 4.0.499 → 4.0.500
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 +8 -6
- package/dist/components/AssetSelectorItem.d.ts +24 -0
- package/dist/components/AssetSelectorItem.js +113 -80
- package/dist/components/CompositionSelector.js +2 -32
- package/dist/components/ControlButton.js +1 -0
- package/dist/components/ExplorerPanel.js +2 -1
- package/dist/components/ExplorerPanelRef.d.ts +2 -0
- package/dist/components/GlobalKeybindings.js +7 -1
- package/dist/components/InlineAction.d.ts +2 -1
- package/dist/components/InlineAction.js +2 -2
- package/dist/components/InlineDropdown.d.ts +1 -1
- package/dist/components/InlineDropdown.js +3 -2
- package/dist/components/InspectorPanel/AlignmentControls.d.ts +2 -2
- package/dist/components/InspectorPanel/AlignmentControls.js +5 -2
- package/dist/components/InspectorPanel/CompositionInspector.js +8 -7
- package/dist/components/InspectorPanel/CompositionMetadata.js +170 -57
- package/dist/components/InspectorPanel/ConnectedCompositionsSection.d.ts +2 -2
- package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -3
- package/dist/components/InspectorPanel/SequenceSelectionInspector.js +7 -7
- package/dist/components/InspectorPanel/common.d.ts +17 -4
- package/dist/components/InspectorPanel/common.js +60 -6
- package/dist/components/InspectorPanel/use-composition-actions.js +1 -0
- package/dist/components/InspectorPanel/use-track-for-selection.d.ts +1 -1
- package/dist/components/InspectorSequenceSection.js +43 -19
- package/dist/components/KeyboardShortcutsExplainer.js +4 -2
- package/dist/components/Menu/MenuItem.js +2 -1
- package/dist/components/MenuCompositionName.js +30 -7
- package/dist/components/MenuToolbar.d.ts +0 -1
- package/dist/components/MenuToolbar.js +8 -7
- package/dist/components/MobilePanel.d.ts +2 -1
- package/dist/components/MobilePanel.js +29 -25
- package/dist/components/ModalContainer.d.ts +1 -0
- package/dist/components/ModalContainer.js +2 -2
- package/dist/components/Modals.js +1 -1
- package/dist/components/NewComposition/DismissableModal.d.ts +1 -0
- package/dist/components/NewComposition/DismissableModal.js +2 -2
- package/dist/components/NewComposition/InputDragger.d.ts +7 -0
- package/dist/components/NewComposition/InputDragger.js +119 -8
- package/dist/components/OutlineToggle.d.ts +1 -3
- package/dist/components/OutlineToggle.js +2 -2
- package/dist/components/PreviewToolbar.js +10 -4
- package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.d.ts +7 -0
- package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +44 -0
- package/dist/components/QuickSwitcher/NoResults.d.ts +1 -1
- package/dist/components/QuickSwitcher/NoResults.js +1 -0
- package/dist/components/QuickSwitcher/QuickSwitcher.d.ts +5 -0
- package/dist/components/QuickSwitcher/QuickSwitcher.js +6 -2
- package/dist/components/QuickSwitcher/QuickSwitcherContent.d.ts +5 -0
- package/dist/components/QuickSwitcher/QuickSwitcherContent.js +76 -12
- package/dist/components/QuickSwitcher/QuickSwitcherResult.d.ts +4 -0
- package/dist/components/QuickSwitcher/QuickSwitcherResult.js +11 -8
- package/dist/components/QuickSwitcher/asset-search.d.ts +9 -0
- package/dist/components/QuickSwitcher/asset-search.js +42 -0
- package/dist/components/SelectedOutlineCropControls.d.ts +8 -0
- package/dist/components/SelectedOutlineCropControls.js +299 -0
- package/dist/components/SelectedOutlineElement.js +83 -43
- package/dist/components/SelectedOutlineOverlay.d.ts +2 -2
- package/dist/components/SelectedOutlineOverlay.js +130 -8
- package/dist/components/SequencePropsSubscriptionProvider.d.ts +2 -0
- package/dist/components/SequencePropsSubscriptionProvider.js +31 -3
- package/dist/components/SidebarCollapserControls.d.ts +3 -1
- package/dist/components/SidebarCollapserControls.js +34 -29
- package/dist/components/SnappingToggle.d.ts +1 -3
- package/dist/components/SnappingToggle.js +2 -2
- package/dist/components/Timeline/TimelineAssetField.d.ts +9 -1
- package/dist/components/Timeline/TimelineAssetField.js +52 -100
- package/dist/components/Timeline/TimelineClipboardKeybindings.d.ts +7 -3
- package/dist/components/Timeline/TimelineClipboardKeybindings.js +65 -38
- package/dist/components/Timeline/TimelineColorField.js +20 -1
- package/dist/components/Timeline/TimelineEffectPropItem.js +8 -77
- package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +1 -0
- package/dist/components/Timeline/TimelineHeightContainer.d.ts +2 -2
- package/dist/components/Timeline/TimelineKeyframeTracksContext.d.ts +3 -3
- package/dist/components/Timeline/TimelineList.d.ts +2 -2
- package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +7 -1
- package/dist/components/Timeline/TimelineSelection.d.ts +5 -5
- package/dist/components/Timeline/TimelineSelection.js +8 -6
- package/dist/components/Timeline/TimelineSequence.js +1 -5
- package/dist/components/Timeline/TimelineSequenceItem.js +57 -10
- package/dist/components/Timeline/TimelineSequencePropItem.js +27 -75
- package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +0 -1
- package/dist/components/Timeline/TimelineTrack.d.ts +2 -2
- package/dist/components/Timeline/TimelineTracks.d.ts +2 -2
- package/dist/components/Timeline/find-track-for-node-path-info.d.ts +1 -1
- package/dist/components/Timeline/get-sequence-context-menu-items.js +14 -12
- package/dist/components/Timeline/reset-selected-timeline-props.js +18 -10
- package/dist/components/Timeline/save-effect-prop.d.ts +10 -0
- package/dist/components/Timeline/save-effect-prop.js +52 -1
- package/dist/components/Timeline/should-show-track-in-timeline.d.ts +2 -2
- package/dist/components/Timeline/timeline-asset-link.js +17 -1
- package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.d.ts +4 -0
- package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +9 -3
- package/dist/components/Timeline/use-timeline-height.d.ts +2 -2
- package/dist/components/TopPanel.js +2 -2
- package/dist/components/UndoRedoButtons.js +27 -5
- package/dist/components/composition-drop-preview.js +1 -0
- package/dist/components/menu-toolbar-height.d.ts +1 -0
- package/dist/components/menu-toolbar-height.js +4 -0
- package/dist/components/selected-outline-drag.d.ts +41 -4
- package/dist/components/selected-outline-drag.js +179 -2
- package/dist/components/selected-outline-geometry.d.ts +1 -0
- package/dist/components/selected-outline-measurement.d.ts +11 -0
- package/dist/components/selected-outline-measurement.js +64 -3
- package/dist/components/selected-outline-types.d.ts +44 -1
- package/dist/components/selected-outline-types.js +21 -1
- package/dist/error-overlay/remotion-overlay/Overlay.js +3 -3
- package/dist/error-overlay/remotion-overlay/ShortcutHint.js +2 -3
- package/dist/esm/{chunk-pk1zwsn1.js → chunk-dr1y1vm3.js} +8417 -7127
- package/dist/esm/internals.mjs +8417 -7127
- package/dist/esm/previewEntry.mjs +51241 -49953
- package/dist/esm/renderEntry.mjs +1 -1
- package/dist/helpers/calculate-timeline.d.ts +2 -2
- package/dist/helpers/calculate-timeline.js +8 -28
- package/dist/helpers/get-timeline-sequence-sort-key.d.ts +3 -10
- package/dist/helpers/get-timeline-sequence-sort-key.js +5 -13
- package/dist/helpers/interactivity-enabled.d.ts +1 -0
- package/dist/helpers/interactivity-enabled.js +7 -2
- package/dist/helpers/is-mac.d.ts +1 -0
- package/dist/helpers/is-mac.js +4 -0
- package/dist/helpers/open-in-editor.d.ts +5 -1
- package/dist/helpers/open-in-editor.js +15 -1
- package/dist/helpers/sort-by-nonce-history.js +97 -19
- package/dist/helpers/use-keybinding.js +2 -3
- package/dist/helpers/use-menu-structure.js +10 -1
- package/dist/icons/caret.d.ts +1 -0
- package/dist/icons/caret.js +2 -2
- package/dist/icons/pen.d.ts +5 -0
- package/dist/icons/pen.js +8 -0
- package/dist/state/modals.d.ts +5 -0
- package/package.json +12 -12
- package/dist/helpers/get-timeline-sequence-hash.d.ts +0 -6
- package/dist/helpers/get-timeline-sequence-hash.js +0 -33
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.SidebarCollapserControl = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
|
|
@@ -18,7 +18,7 @@ const style = {
|
|
|
18
18
|
color: colors_1.CURRENT_COLOR,
|
|
19
19
|
position: 'relative',
|
|
20
20
|
};
|
|
21
|
-
const
|
|
21
|
+
const SidebarCollapserControl = ({ side }) => {
|
|
22
22
|
const { setSidebarCollapsedState, sidebarCollapsedStateRight } = (0, react_1.useContext)(sidebar_1.SidebarContext);
|
|
23
23
|
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
24
24
|
const leftSidebarStatus = (0, TopPanel_1.useResponsiveSidebarStatus)();
|
|
@@ -83,15 +83,30 @@ const SidebarCollapserControls = () => {
|
|
|
83
83
|
toggleRight,
|
|
84
84
|
]);
|
|
85
85
|
(0, react_1.useEffect)(() => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
if (side === 'left') {
|
|
87
|
+
const left = keybindings.registerKeybinding({
|
|
88
|
+
event: 'keydown',
|
|
89
|
+
key: 'b',
|
|
90
|
+
commandCtrlKey: true,
|
|
91
|
+
callback: toggleLeft,
|
|
92
|
+
preventDefault: true,
|
|
93
|
+
triggerIfInputFieldFocused: false,
|
|
94
|
+
keepRegisteredWhenNotHighestContext: false,
|
|
95
|
+
});
|
|
96
|
+
const zen = keybindings.registerKeybinding({
|
|
97
|
+
event: 'keydown',
|
|
98
|
+
key: 'g',
|
|
99
|
+
commandCtrlKey: true,
|
|
100
|
+
callback: toggleBoth,
|
|
101
|
+
preventDefault: true,
|
|
102
|
+
triggerIfInputFieldFocused: false,
|
|
103
|
+
keepRegisteredWhenNotHighestContext: false,
|
|
104
|
+
});
|
|
105
|
+
return () => {
|
|
106
|
+
left.unregister();
|
|
107
|
+
zen.unregister();
|
|
108
|
+
};
|
|
109
|
+
}
|
|
95
110
|
const right = keybindings.registerKeybinding({
|
|
96
111
|
event: 'keydown',
|
|
97
112
|
key: 'j',
|
|
@@ -101,21 +116,10 @@ const SidebarCollapserControls = () => {
|
|
|
101
116
|
triggerIfInputFieldFocused: false,
|
|
102
117
|
keepRegisteredWhenNotHighestContext: false,
|
|
103
118
|
});
|
|
104
|
-
const zen = keybindings.registerKeybinding({
|
|
105
|
-
event: 'keydown',
|
|
106
|
-
key: 'g',
|
|
107
|
-
commandCtrlKey: true,
|
|
108
|
-
callback: toggleBoth,
|
|
109
|
-
preventDefault: true,
|
|
110
|
-
triggerIfInputFieldFocused: false,
|
|
111
|
-
keepRegisteredWhenNotHighestContext: false,
|
|
112
|
-
});
|
|
113
119
|
return () => {
|
|
114
|
-
left.unregister();
|
|
115
120
|
right.unregister();
|
|
116
|
-
zen.unregister();
|
|
117
121
|
};
|
|
118
|
-
}, [keybindings, toggleBoth, toggleLeft, toggleRight]);
|
|
122
|
+
}, [keybindings, side, toggleBoth, toggleLeft, toggleRight]);
|
|
119
123
|
const toggleLeftTooltip = (0, use_keybinding_1.areKeyboardShortcutsDisabled)()
|
|
120
124
|
? 'Toggle Left Sidebar'
|
|
121
125
|
: `Toggle Left Sidebar (${ShortcutHint_1.cmdOrCtrlCharacter}+B)`;
|
|
@@ -129,13 +133,14 @@ const SidebarCollapserControls = () => {
|
|
|
129
133
|
};
|
|
130
134
|
}, []);
|
|
131
135
|
const toggleLeftAction = (0, react_1.useCallback)((color) => {
|
|
132
|
-
return (jsx_runtime_1.jsx("div", { style: colorStyle(color), title: toggleLeftTooltip, children: jsx_runtime_1.jsx("div", { style: leftIcon(color) }) }));
|
|
136
|
+
return (jsx_runtime_1.jsx("div", { "data-sidebar-toggle": "left", style: colorStyle(color), title: toggleLeftTooltip, children: jsx_runtime_1.jsx("div", { style: leftIcon(color) }) }));
|
|
133
137
|
}, [colorStyle, leftIcon, toggleLeftTooltip]);
|
|
134
138
|
const toggleRightAction = (0, react_1.useCallback)((color) => {
|
|
135
|
-
return (jsx_runtime_1.jsx("div", { style: colorStyle(color), title: toggleRightTooltip, children: jsx_runtime_1.jsx("div", { style: rightIcon(color) }) }));
|
|
139
|
+
return (jsx_runtime_1.jsx("div", { "data-sidebar-toggle": "right", style: colorStyle(color), title: toggleRightTooltip, children: jsx_runtime_1.jsx("div", { style: rightIcon(color) }) }));
|
|
136
140
|
}, [colorStyle, rightIcon, toggleRightTooltip]);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
if (side === 'left') {
|
|
142
|
+
return (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: toggleLeft, renderAction: toggleLeftAction, unhoveredColor: colors_1.WHITE_ALPHA_80 }));
|
|
143
|
+
}
|
|
144
|
+
return (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: toggleRight, renderAction: toggleRightAction, unhoveredColor: colors_1.WHITE_ALPHA_80 }));
|
|
140
145
|
};
|
|
141
|
-
exports.
|
|
146
|
+
exports.SidebarCollapserControl = SidebarCollapserControl;
|
|
@@ -9,7 +9,7 @@ const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
|
9
9
|
const magnet_1 = require("../icons/magnet");
|
|
10
10
|
const editor_snapping_1 = require("../state/editor-snapping");
|
|
11
11
|
const ControlButton_1 = require("./ControlButton");
|
|
12
|
-
const SnappingToggle = (
|
|
12
|
+
const SnappingToggle = () => {
|
|
13
13
|
const { editorSnapping, setEditorSnapping } = (0, react_1.useContext)(editor_snapping_1.EditorSnappingContext);
|
|
14
14
|
const onClick = (0, react_1.useCallback)(() => {
|
|
15
15
|
setEditorSnapping((current) => !current);
|
|
@@ -21,6 +21,6 @@ const SnappingToggle = ({ disabled }) => {
|
|
|
21
21
|
]
|
|
22
22
|
.filter(no_react_1.NoReactInternals.truthy)
|
|
23
23
|
.join(' ');
|
|
24
|
-
return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, "aria-pressed": editorSnapping, "aria-keyshortcuts": "Shift+M",
|
|
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
25
|
};
|
|
26
26
|
exports.SnappingToggle = SnappingToggle;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { CanUpdateSequencePropStatusStatic } from 'remotion';
|
|
3
3
|
import type { SchemaFieldInfo, TimelineFieldOnDragValueChange, TimelineFieldOnSave } from '../../helpers/timeline-layout';
|
|
4
|
+
import { type InspectorInlineActionProps } from '../InspectorPanel/common';
|
|
5
|
+
export type InspectorSourceAction = Omit<InspectorInlineActionProps, 'variant'>;
|
|
6
|
+
type AssetSelectionContextValue = {
|
|
7
|
+
readonly initialQuery: string;
|
|
8
|
+
readonly getSourceAction: (src: string) => InspectorSourceAction | null;
|
|
9
|
+
readonly sourceAction: InspectorSourceAction | null;
|
|
10
|
+
};
|
|
11
|
+
export declare const AssetSelectionContext: React.Context<AssetSelectionContextValue>;
|
|
12
|
+
export declare const toFileToken: (name: string) => string;
|
|
4
13
|
type TimelineAssetFieldProps = {
|
|
5
14
|
readonly field: SchemaFieldInfo;
|
|
6
15
|
readonly propStatus: CanUpdateSequencePropStatusStatic;
|
|
@@ -9,6 +18,5 @@ type TimelineAssetFieldProps = {
|
|
|
9
18
|
readonly onDragValueChange: TimelineFieldOnDragValueChange;
|
|
10
19
|
readonly onDragEnd: () => void;
|
|
11
20
|
};
|
|
12
|
-
export declare const isStaticFileAssetValue: (value: unknown) => value is string;
|
|
13
21
|
export declare const TimelineAssetField: React.FC<TimelineAssetFieldProps>;
|
|
14
22
|
export {};
|
|
@@ -1,45 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TimelineAssetField = exports.
|
|
3
|
+
exports.TimelineAssetField = exports.toFileToken = exports.AssetSelectionContext = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const no_react_1 = require("remotion/no-react");
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
maxWidth: 180,
|
|
16
|
-
};
|
|
17
|
-
const remoteAssetStyle = {
|
|
18
|
-
display: 'inline-block',
|
|
19
|
-
marginLeft: 8,
|
|
20
|
-
maxWidth: 180,
|
|
21
|
-
overflow: 'hidden',
|
|
22
|
-
textOverflow: 'ellipsis',
|
|
23
|
-
verticalAlign: 'middle',
|
|
24
|
-
whiteSpace: 'nowrap',
|
|
7
|
+
const pen_1 = require("../../icons/pen");
|
|
8
|
+
const modals_1 = require("../../state/modals");
|
|
9
|
+
const InlineAction_1 = require("../InlineAction");
|
|
10
|
+
const common_1 = require("../InspectorPanel/common");
|
|
11
|
+
const penIcon = {
|
|
12
|
+
display: 'block',
|
|
13
|
+
height: 14,
|
|
14
|
+
width: 14,
|
|
25
15
|
};
|
|
16
|
+
exports.AssetSelectionContext = (0, react_1.createContext)({
|
|
17
|
+
getSourceAction: () => null,
|
|
18
|
+
initialQuery: '',
|
|
19
|
+
sourceAction: null,
|
|
20
|
+
});
|
|
26
21
|
const toFileToken = (name) => {
|
|
27
22
|
return `${no_react_1.NoReactInternals.FILE_TOKEN}${name
|
|
28
23
|
.split('/')
|
|
29
24
|
.map(encodeURIComponent)
|
|
30
25
|
.join('/')}`;
|
|
31
26
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
exports.toFileToken = toFileToken;
|
|
28
|
+
const TimelineAssetField = ({ field, effectiveValue, propStatus, onSave, onDragValueChange, onDragEnd, }) => {
|
|
29
|
+
if (field.fieldSchema.type !== 'asset') {
|
|
30
|
+
throw new Error('TimelineAssetField rendered for non-asset field');
|
|
31
|
+
}
|
|
32
|
+
const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
|
|
33
|
+
const { getSourceAction, initialQuery, sourceAction } = (0, react_1.useContext)(exports.AssetSelectionContext);
|
|
34
|
+
const inlineSourceAction = (0, react_1.useMemo)(() => {
|
|
35
|
+
if (field.key !== 'src') {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return typeof effectiveValue === 'string'
|
|
39
|
+
? getSourceAction(effectiveValue)
|
|
40
|
+
: sourceAction;
|
|
41
|
+
}, [effectiveValue, field.key, getSourceAction, sourceAction]);
|
|
42
|
+
const onSelect = (0, react_1.useCallback)((assetName, previewValue) => {
|
|
43
|
+
const sourceValue = (0, exports.toFileToken)(assetName);
|
|
43
44
|
if (sourceValue === propStatus.codeValue) {
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
@@ -48,78 +49,29 @@ const TimelineStaticFileAssetField = ({ propStatus, effectiveValue, onSave, onDr
|
|
|
48
49
|
onDragEnd();
|
|
49
50
|
});
|
|
50
51
|
}, [propStatus.codeValue, onDragValueChange, onSave, onDragEnd]);
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
if (!existing) {
|
|
63
|
-
await (0, write_static_file_1.writeStaticFile)({
|
|
64
|
-
contents: await file.arrayBuffer(),
|
|
65
|
-
filePath: file.name,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
const fileToken = toFileToken(file.name);
|
|
69
|
-
onSelect(fileToken, toStaticFileUrl(fileToken));
|
|
70
|
-
if (!existing) {
|
|
71
|
-
(0, NotificationCenter_1.showNotification)(`Created ${file.name} in public folder`, 3000);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
(0, NotificationCenter_1.showNotification)(`Could not upload asset: ${error instanceof Error ? error.message : String(error)}`, 4000);
|
|
76
|
-
}
|
|
77
|
-
}, [onSelect, staticFiles]);
|
|
78
|
-
const items = (0, react_1.useMemo)(() => {
|
|
79
|
-
const publicFileItems = staticFiles.map((file) => {
|
|
80
|
-
const fileToken = toFileToken(file.name);
|
|
81
|
-
return {
|
|
82
|
-
type: 'item',
|
|
83
|
-
id: fileToken,
|
|
84
|
-
value: fileToken,
|
|
85
|
-
label: file.name,
|
|
86
|
-
onClick: () => onSelect(fileToken, file.src),
|
|
87
|
-
keyHint: null,
|
|
88
|
-
leftItem: fileToken === current ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
|
|
89
|
-
subMenu: null,
|
|
90
|
-
quickSwitcherLabel: null,
|
|
91
|
-
};
|
|
52
|
+
const openAssetSelection = (0, react_1.useCallback)(() => {
|
|
53
|
+
setSelectedModal({
|
|
54
|
+
type: 'quick-switcher',
|
|
55
|
+
mode: 'assets',
|
|
56
|
+
invocationTimestamp: Date.now(),
|
|
57
|
+
assetSelection: {
|
|
58
|
+
initialQuery,
|
|
59
|
+
onSelected: (asset) => onSelect(asset.name, asset.src),
|
|
60
|
+
},
|
|
92
61
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
onClick: () => {
|
|
102
|
-
upload().catch(() => undefined);
|
|
103
|
-
},
|
|
104
|
-
keyHint: null,
|
|
105
|
-
leftItem: null,
|
|
106
|
-
subMenu: null,
|
|
107
|
-
quickSwitcherLabel: null,
|
|
62
|
+
}, [initialQuery, onSelect, setSelectedModal]);
|
|
63
|
+
const action = (jsx_runtime_1.jsx(InlineAction_1.InlineAction, { onClick: openAssetSelection, disabled: window.remotion_isReadOnlyStudio, title: "Change source", renderAction: (color) => jsx_runtime_1.jsx(pen_1.PenIcon, { color: color, style: penIcon }) }));
|
|
64
|
+
if (inlineSourceAction === null) {
|
|
65
|
+
return action;
|
|
66
|
+
}
|
|
67
|
+
return (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { ...inlineSourceAction, size: "compact", variant: {
|
|
68
|
+
type: 'segmented',
|
|
69
|
+
trailing: {
|
|
108
70
|
disabled: window.remotion_isReadOnlyStudio,
|
|
71
|
+
onClick: openAssetSelection,
|
|
72
|
+
renderIcon: (color) => jsx_runtime_1.jsx(pen_1.PenIcon, { color: color, style: penIcon }),
|
|
73
|
+
title: 'Change source',
|
|
109
74
|
},
|
|
110
|
-
|
|
111
|
-
}, [current, onSelect, staticFiles, upload]);
|
|
112
|
-
return (jsx_runtime_1.jsx(ComboBox_1.Combobox, { size: "small", title: current, selectedId: current, values: items, style: comboboxStyle }));
|
|
113
|
-
};
|
|
114
|
-
const TimelineAssetField = (props) => {
|
|
115
|
-
var _a;
|
|
116
|
-
if (props.field.fieldSchema.type !== 'asset') {
|
|
117
|
-
throw new Error('TimelineAssetField rendered for non-asset field');
|
|
118
|
-
}
|
|
119
|
-
if (!(0, exports.isStaticFileAssetValue)(props.effectiveValue)) {
|
|
120
|
-
const remote = String((_a = props.effectiveValue) !== null && _a !== void 0 ? _a : '');
|
|
121
|
-
return (jsx_runtime_1.jsx("span", { style: remoteAssetStyle, title: remote, children: remote }));
|
|
122
|
-
}
|
|
123
|
-
return jsx_runtime_1.jsx(TimelineStaticFileAssetField, { ...props });
|
|
75
|
+
} }));
|
|
124
76
|
};
|
|
125
77
|
exports.TimelineAssetField = TimelineAssetField;
|
|
@@ -14,16 +14,19 @@ export type PasteEffectsTarget = {
|
|
|
14
14
|
} | {
|
|
15
15
|
readonly type: 'unsupported';
|
|
16
16
|
};
|
|
17
|
-
|
|
18
|
-
readonly type: 'valid';
|
|
17
|
+
type PasteEffectPropEditTarget = {
|
|
19
18
|
readonly fileName: string;
|
|
20
19
|
readonly nodePath: SequencePropsSubscriptionKey;
|
|
21
20
|
readonly effectIndex: number;
|
|
22
21
|
readonly fieldKey: string;
|
|
23
22
|
readonly defaultValue: string | null;
|
|
24
23
|
readonly schema: InteractivitySchema;
|
|
24
|
+
};
|
|
25
|
+
export type PasteEffectPropTarget = {
|
|
26
|
+
readonly type: 'valid';
|
|
27
|
+
readonly targets: PasteEffectPropEditTarget[];
|
|
25
28
|
} | {
|
|
26
|
-
readonly type: 'none' | '
|
|
29
|
+
readonly type: 'none' | 'unsupported' | 'effect-type-mismatch' | 'prop-mismatch' | 'uncopyable';
|
|
27
30
|
};
|
|
28
31
|
export declare const getPasteEffectsTarget: (selectedItems: readonly TimelineSelection[]) => PasteEffectsTarget;
|
|
29
32
|
export declare const getSnapshotsFromSelection: ({ selection, propStatuses, }: {
|
|
@@ -72,3 +75,4 @@ export declare const getPasteEffectPropTarget: ({ selectedItems, payload, propSt
|
|
|
72
75
|
readonly overrideIdsToNodePaths: OverrideIdToNodePaths;
|
|
73
76
|
}) => PasteEffectPropTarget;
|
|
74
77
|
export declare const TimelineClipboardKeybindings: React.FC;
|
|
78
|
+
export {};
|
|
@@ -285,18 +285,8 @@ const getEasingClipboardDataFromSelection = ({ selection, sequences, overrideIds
|
|
|
285
285
|
};
|
|
286
286
|
};
|
|
287
287
|
exports.getEasingClipboardDataFromSelection = getEasingClipboardDataFromSelection;
|
|
288
|
-
const
|
|
288
|
+
const getPasteEffectPropTargetForSelection = ({ selection, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
|
|
289
289
|
var _a;
|
|
290
|
-
if (selectedItems.length === 0) {
|
|
291
|
-
return { type: 'none' };
|
|
292
|
-
}
|
|
293
|
-
if (selectedItems.length !== 1) {
|
|
294
|
-
return { type: 'multiple' };
|
|
295
|
-
}
|
|
296
|
-
const [selection] = selectedItems;
|
|
297
|
-
if (!selection) {
|
|
298
|
-
return { type: 'none' };
|
|
299
|
-
}
|
|
300
290
|
if (selection.type !== 'sequence-effect-prop' &&
|
|
301
291
|
selection.type !== 'sequence-effect') {
|
|
302
292
|
return { type: 'none' };
|
|
@@ -348,12 +338,42 @@ const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequen
|
|
|
348
338
|
}
|
|
349
339
|
return {
|
|
350
340
|
type: 'valid',
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
341
|
+
target: {
|
|
342
|
+
fileName: selection.nodePathInfo.sequenceSubscriptionKey.absolutePath,
|
|
343
|
+
nodePath: selection.nodePathInfo.sequenceSubscriptionKey,
|
|
344
|
+
effectIndex: target.effectIndex,
|
|
345
|
+
fieldKey: target.fieldKey,
|
|
346
|
+
defaultValue: getDefaultValue(fieldSchema),
|
|
347
|
+
schema: effect.schema,
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
const getPasteEffectPropTarget = ({ selectedItems, payload, propStatuses, sequences, overrideIdsToNodePaths, }) => {
|
|
352
|
+
if (selectedItems.length === 0) {
|
|
353
|
+
return { type: 'none' };
|
|
354
|
+
}
|
|
355
|
+
const targets = [];
|
|
356
|
+
for (const selection of selectedItems) {
|
|
357
|
+
const result = getPasteEffectPropTargetForSelection({
|
|
358
|
+
selection,
|
|
359
|
+
payload,
|
|
360
|
+
propStatuses,
|
|
361
|
+
sequences,
|
|
362
|
+
overrideIdsToNodePaths,
|
|
363
|
+
});
|
|
364
|
+
if (result.type !== 'valid') {
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
targets.push(result.target);
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
type: 'valid',
|
|
371
|
+
targets: [
|
|
372
|
+
...new Map(targets.map((target) => [
|
|
373
|
+
`${makeTargetKey(target.nodePath)}:${target.effectIndex}:${target.fieldKey}`,
|
|
374
|
+
target,
|
|
375
|
+
])).values(),
|
|
376
|
+
],
|
|
357
377
|
};
|
|
358
378
|
};
|
|
359
379
|
exports.getPasteEffectPropTarget = getPasteEffectPropTarget;
|
|
@@ -730,11 +750,8 @@ const TimelineClipboardKeybindings = () => {
|
|
|
730
750
|
});
|
|
731
751
|
if (effectPropTarget.type !== 'valid') {
|
|
732
752
|
switch (effectPropTarget.type) {
|
|
733
|
-
case 'multiple':
|
|
734
|
-
(0, NotificationCenter_1.showNotification)('Select one target effect prop or effect to paste onto', 3000);
|
|
735
|
-
return;
|
|
736
753
|
case 'none':
|
|
737
|
-
(0, NotificationCenter_1.showNotification)('Select
|
|
754
|
+
(0, NotificationCenter_1.showNotification)('Select matching effect props or effects to paste onto', 3000);
|
|
738
755
|
return;
|
|
739
756
|
case 'unsupported':
|
|
740
757
|
(0, NotificationCenter_1.showNotification)('This sequence does not support effects', 3000);
|
|
@@ -752,26 +769,36 @@ const TimelineClipboardKeybindings = () => {
|
|
|
752
769
|
throw new Error(`Unexpected paste target: ${effectPropTarget}`);
|
|
753
770
|
}
|
|
754
771
|
}
|
|
755
|
-
return (0, save_effect_prop_1.
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
772
|
+
return (0, save_effect_prop_1.saveMultipleEffectProps)({
|
|
773
|
+
changes: effectPropTarget.targets.map((pasteTarget) => ({
|
|
774
|
+
fileName: pasteTarget.fileName,
|
|
775
|
+
nodePath: pasteTarget.nodePath,
|
|
776
|
+
effectIndex: pasteTarget.effectIndex,
|
|
777
|
+
fieldKey: pasteTarget.fieldKey,
|
|
778
|
+
...(effectPropResult.data.param.type === 'static'
|
|
779
|
+
? {
|
|
780
|
+
type: 'value',
|
|
781
|
+
value: effectPropResult.data.param.value,
|
|
782
|
+
}
|
|
783
|
+
: {
|
|
784
|
+
type: 'effect-param',
|
|
785
|
+
effectParam: effectPropResult.data.param,
|
|
786
|
+
}),
|
|
787
|
+
defaultValue: pasteTarget.defaultValue,
|
|
788
|
+
schema: pasteTarget.schema,
|
|
789
|
+
})),
|
|
771
790
|
setPropStatuses,
|
|
772
791
|
clientId,
|
|
792
|
+
undoLabel: effectPropTarget.targets.length > 1
|
|
793
|
+
? 'Paste effect prop onto selected effects'
|
|
794
|
+
: 'Paste effect prop',
|
|
795
|
+
redoLabel: effectPropTarget.targets.length > 1
|
|
796
|
+
? 'Reapply effect prop paste onto selected effects'
|
|
797
|
+
: 'Reapply effect prop paste',
|
|
773
798
|
}).then(() => {
|
|
774
|
-
(0, NotificationCenter_1.showNotification)(
|
|
799
|
+
(0, NotificationCenter_1.showNotification)(effectPropTarget.targets.length > 1
|
|
800
|
+
? 'Pasted effect prop onto selected effects'
|
|
801
|
+
: 'Pasted effect prop', 2000);
|
|
775
802
|
});
|
|
776
803
|
}
|
|
777
804
|
const result = envelope === null
|
|
@@ -12,8 +12,22 @@ const containerStyle = {
|
|
|
12
12
|
};
|
|
13
13
|
const SWATCH_WIDTH = 20;
|
|
14
14
|
const SWATCH_HEIGHT = 15;
|
|
15
|
+
const DEFAULT_SET_COLOR = '#808080';
|
|
16
|
+
const noneLabelStyle = {
|
|
17
|
+
color: colors_1.LIGHT_TEXT,
|
|
18
|
+
fontSize: 12,
|
|
19
|
+
};
|
|
20
|
+
const setButtonStyle = {
|
|
21
|
+
background: 'none',
|
|
22
|
+
border: 'none',
|
|
23
|
+
color: colors_1.BLUE,
|
|
24
|
+
cursor: 'pointer',
|
|
25
|
+
fontSize: 12,
|
|
26
|
+
margin: 0,
|
|
27
|
+
padding: 0,
|
|
28
|
+
};
|
|
15
29
|
const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragValueChange, onDragEnd, }) => {
|
|
16
|
-
var _a;
|
|
30
|
+
var _a, _b;
|
|
17
31
|
const currentValue = typeof effectiveValue === 'string'
|
|
18
32
|
? effectiveValue
|
|
19
33
|
: field.fieldSchema.type === 'color'
|
|
@@ -33,6 +47,11 @@ const TimelineColorField = ({ field, effectiveValue, propStatus, onSave, onDragV
|
|
|
33
47
|
marginLeft: 5,
|
|
34
48
|
};
|
|
35
49
|
}, []);
|
|
50
|
+
if (currentValue === 'none') {
|
|
51
|
+
return (jsx_runtime_1.jsxs("span", { style: containerStyle, children: [
|
|
52
|
+
jsx_runtime_1.jsx("span", { style: noneLabelStyle, children: "None" }), jsx_runtime_1.jsx("button", { type: "button", style: setButtonStyle, title: `Set ${(_b = field.description) !== null && _b !== void 0 ? _b : field.key} to gray`, onClick: () => onChangeComplete(DEFAULT_SET_COLOR), children: "Set" })
|
|
53
|
+
] }));
|
|
54
|
+
}
|
|
36
55
|
return (jsx_runtime_1.jsx("span", { style: containerStyle, children: jsx_runtime_1.jsx(ColorPicker_1.ColorPicker, { value: currentValue, status: "ok", onChange: onChange, onChangeComplete: onChangeComplete, width: SWATCH_WIDTH, height: SWATCH_HEIGHT, disabled: false, name: field.key, title: currentValue, style: swatchStyle }) }));
|
|
37
56
|
};
|
|
38
57
|
exports.TimelineColorField = TimelineColorField;
|
|
@@ -6,10 +6,10 @@ const studio_shared_1 = require("@remotion/studio-shared");
|
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const remotion_1 = require("remotion");
|
|
8
8
|
const client_id_1 = require("../../helpers/client-id");
|
|
9
|
+
const open_in_editor_1 = require("../../helpers/open-in-editor");
|
|
9
10
|
const call_api_1 = require("../call-api");
|
|
10
11
|
const ContextMenu_1 = require("../ContextMenu");
|
|
11
12
|
const call_add_keyframe_1 = require("./call-add-keyframe");
|
|
12
|
-
const get_animation_item_selection_for_frame_1 = require("./get-animation-item-selection-for-frame");
|
|
13
13
|
const get_timeline_keyframes_1 = require("./get-timeline-keyframes");
|
|
14
14
|
const save_effect_prop_1 = require("./save-effect-prop");
|
|
15
15
|
const save_prop_queue_1 = require("./save-prop-queue");
|
|
@@ -21,7 +21,6 @@ const TimelineLayerEye_1 = require("./TimelineLayerEye");
|
|
|
21
21
|
const TimelineRowChrome_1 = require("./TimelineRowChrome");
|
|
22
22
|
const TimelineSchemaField_1 = require("./TimelineSchemaField");
|
|
23
23
|
const TimelineSelection_1 = require("./TimelineSelection");
|
|
24
|
-
const update_selected_easing_1 = require("./update-selected-easing");
|
|
25
24
|
const fieldRowBase = {};
|
|
26
25
|
const isKeyframedStatus = (status) => {
|
|
27
26
|
return status.status === 'keyframed';
|
|
@@ -218,9 +217,6 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
|
|
|
218
217
|
const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
|
|
219
218
|
const { getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
|
|
220
219
|
const selection = (0, TimelineSelection_1.useTimelineRowSelection)(nodePathInfo);
|
|
221
|
-
const { selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
|
|
222
|
-
const setFrame = remotion_1.Internals.useTimelineSetFrame();
|
|
223
|
-
const videoConfig = (0, remotion_1.useVideoConfig)();
|
|
224
220
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
225
221
|
const sourceFrame = timelinePosition - keyframeDisplayOffset;
|
|
226
222
|
const style = (0, react_1.useMemo)(() => {
|
|
@@ -314,82 +310,17 @@ const TimelineEffectPropItem = ({ field, validatedLocation, rowDepth, nodePath,
|
|
|
314
310
|
},
|
|
315
311
|
];
|
|
316
312
|
}, [canShowReset, onReset]);
|
|
317
|
-
const seekToDisplayFrame = (0, react_1.useCallback)((frame) => {
|
|
318
|
-
setFrame((current) => {
|
|
319
|
-
const next = { ...current, [videoConfig.id]: frame };
|
|
320
|
-
remotion_1.Internals.persistCurrentFrame(next);
|
|
321
|
-
return next;
|
|
322
|
-
});
|
|
323
|
-
}, [setFrame, videoConfig.id]);
|
|
324
313
|
const onPropertyDoubleClick = (0, react_1.useCallback)((event) => {
|
|
325
|
-
if (
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
const keyframeSelection = {
|
|
329
|
-
type: 'keyframe',
|
|
330
|
-
nodePathInfo,
|
|
331
|
-
frame: sourceFrame + keyframeDisplayOffset,
|
|
332
|
-
};
|
|
333
|
-
if (propStatus.status === 'static') {
|
|
334
|
-
if (!keyframable || previewServerState.type !== 'connected') {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
const value = remotion_1.Internals.getEffectiveVisualModeValue({
|
|
338
|
-
propStatus,
|
|
339
|
-
dragOverrideValue,
|
|
340
|
-
frame: sourceFrame,
|
|
341
|
-
defaultValue: field.fieldSchema.default,
|
|
342
|
-
shouldResortToDefaultValueIfUndefined: true,
|
|
343
|
-
});
|
|
344
|
-
event.stopPropagation();
|
|
345
|
-
(0, call_add_keyframe_1.callAddEffectKeyframe)({
|
|
346
|
-
fileName: validatedLocation.source,
|
|
347
|
-
nodePath,
|
|
348
|
-
effectIndex: field.effectIndex,
|
|
349
|
-
fieldKey: field.key,
|
|
350
|
-
sourceFrame,
|
|
351
|
-
value,
|
|
352
|
-
schema: field.effectSchema,
|
|
353
|
-
setPropStatuses,
|
|
354
|
-
clientId: previewServerState.clientId,
|
|
355
|
-
}).catch(() => undefined);
|
|
356
|
-
selectItems([keyframeSelection], { reveal: true });
|
|
357
|
-
seekToDisplayFrame(keyframeSelection.frame);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
const targetSelection = (0, get_animation_item_selection_for_frame_1.getAnimationItemSelectionForSourceFrame)({
|
|
361
|
-
includeEasings: (0, update_selected_easing_1.canEditEasingForInterpolationFunction)(propStatus.interpolationFunction),
|
|
362
|
-
keyframeDisplayOffset,
|
|
363
|
-
keyframes: propStatus.keyframes,
|
|
364
|
-
nodePathInfo,
|
|
365
|
-
sourceFrame,
|
|
366
|
-
});
|
|
367
|
-
if (targetSelection === null) {
|
|
314
|
+
if (!window.remotion_editorName ||
|
|
315
|
+
previewServerState.type !== 'connected') {
|
|
368
316
|
return;
|
|
369
317
|
}
|
|
370
318
|
event.stopPropagation();
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
375
|
-
}, [
|
|
376
|
-
dragOverrideValue,
|
|
377
|
-
field.effectIndex,
|
|
378
|
-
field.effectSchema,
|
|
379
|
-
field.fieldSchema.default,
|
|
380
|
-
field.key,
|
|
381
|
-
keyframeDisplayOffset,
|
|
382
|
-
keyframable,
|
|
383
|
-
nodePath,
|
|
384
|
-
nodePathInfo,
|
|
385
|
-
previewServerState,
|
|
386
|
-
propStatus,
|
|
387
|
-
seekToDisplayFrame,
|
|
388
|
-
selectItems,
|
|
389
|
-
setPropStatuses,
|
|
390
|
-
sourceFrame,
|
|
391
|
-
validatedLocation.source,
|
|
392
|
-
]);
|
|
319
|
+
(0, open_in_editor_1.openOriginalPositionInEditorAtProperty)({
|
|
320
|
+
originalPosition: validatedLocation,
|
|
321
|
+
property: field.key,
|
|
322
|
+
}).catch(() => undefined);
|
|
323
|
+
}, [field.key, previewServerState.type, validatedLocation]);
|
|
393
324
|
const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, children: jsx_runtime_1.jsx(exports.TimelineEffectPropValue, { field: field, nodePath: nodePath, validatedLocation: validatedLocation, sourceFrame: sourceFrame }) }) }));
|
|
394
325
|
return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenuValues, onOpen: selection.selectable ? selection.onSelect : null, children: row }));
|
|
395
326
|
};
|