@remotion/studio 4.0.500 → 4.0.501

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/Studio.js +1 -1
  2. package/dist/api/delete-static-file.js +8 -3
  3. package/dist/api/rename-static-file.js +8 -0
  4. package/dist/api/watch-public-folder.js +2 -1
  5. package/dist/api/watch-static-file.js +2 -1
  6. package/dist/api/write-static-file.js +8 -3
  7. package/dist/components/AssetSelector.js +3 -1
  8. package/dist/components/AssetSelectorItem.d.ts +2 -1
  9. package/dist/components/AssetSelectorItem.js +5 -2
  10. package/dist/components/Canvas.js +6 -1
  11. package/dist/components/CaptionInspector.d.ts +10 -0
  12. package/dist/components/CaptionInspector.js +24 -0
  13. package/dist/components/CaptionTextEditor.d.ts +9 -0
  14. package/dist/components/CaptionTextEditor.js +132 -0
  15. package/dist/components/CurrentAsset.js +3 -2
  16. package/dist/components/EditorContexts.d.ts +0 -1
  17. package/dist/components/EditorContexts.js +2 -2
  18. package/dist/components/FpsCounter.js +3 -3
  19. package/dist/components/FullscreenToggle.js +2 -1
  20. package/dist/components/GlobalKeybindings.js +2 -0
  21. package/dist/components/InitialCompositionLoader.d.ts +1 -1
  22. package/dist/components/InlineAction.js +1 -0
  23. package/dist/components/InlineCaptionInspector.d.ts +11 -0
  24. package/dist/components/InlineCaptionInspector.js +108 -0
  25. package/dist/components/InspectorPanel/CompositionInspector.js +5 -3
  26. package/dist/components/InspectorPanel/SelectedInspector.d.ts +1 -0
  27. package/dist/components/InspectorPanel/SelectedInspector.js +2 -2
  28. package/dist/components/InspectorPanel/SequenceSelectionInspector.d.ts +1 -0
  29. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +4 -4
  30. package/dist/components/InspectorPanel/inspector-section-collapse.d.ts +22 -0
  31. package/dist/components/InspectorPanel/inspector-section-collapse.js +165 -0
  32. package/dist/components/InspectorPanel/styles.js +7 -1
  33. package/dist/components/InspectorPanel/use-composition-actions.d.ts +3 -0
  34. package/dist/components/InspectorPanel/use-composition-actions.js +91 -6
  35. package/dist/components/InspectorPanel.js +2 -2
  36. package/dist/components/InspectorSequenceSection.d.ts +2 -1
  37. package/dist/components/InspectorSequenceSection.js +238 -8
  38. package/dist/components/MenuToolbar.js +8 -1
  39. package/dist/components/Modals.js +1 -1
  40. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +1 -0
  41. package/dist/components/QuickSwitcher/QuickSwitcher.d.ts +5 -0
  42. package/dist/components/QuickSwitcher/QuickSwitcher.js +2 -2
  43. package/dist/components/QuickSwitcher/QuickSwitcherContent.d.ts +5 -0
  44. package/dist/components/QuickSwitcher/QuickSwitcherContent.js +26 -8
  45. package/dist/components/RenderQueue/ClientRenderQueueProcessor.d.ts +0 -1
  46. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +3 -14
  47. package/dist/components/RenderQueue/RenderQueueDownloadItem.js +2 -2
  48. package/dist/components/SelectedOutlineElement.js +1 -4
  49. package/dist/components/SelectedOutlineOverlay.js +17 -8
  50. package/dist/components/ShowOutlinesProvider.js +4 -1
  51. package/dist/components/Timeline/Timeline.js +19 -5
  52. package/dist/components/Timeline/TimelineAssetField.js +1 -0
  53. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +8 -2
  54. package/dist/components/Timeline/TimelinePrimitiveFieldValue.d.ts +7 -2
  55. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +3 -1
  56. package/dist/components/Timeline/TimelineRowChrome.d.ts +3 -0
  57. package/dist/components/Timeline/TimelineRowChrome.js +4 -3
  58. package/dist/components/Timeline/TimelineSelection.d.ts +4 -2
  59. package/dist/components/Timeline/TimelineSelection.js +9 -6
  60. package/dist/components/Timeline/TimelineSequence.js +1 -4
  61. package/dist/components/Timeline/TimelineSequenceItem.js +4 -5
  62. package/dist/components/Timeline/TimelineSequencePropItem.js +9 -10
  63. package/dist/components/Timeline/TimelineTrack.js +4 -2
  64. package/dist/components/Timeline/border-radius-representation.d.ts +16 -0
  65. package/dist/components/Timeline/border-radius-representation.js +60 -0
  66. package/dist/components/Timeline/delete-selected-timeline-item.js +1 -6
  67. package/dist/components/Timeline/get-sequence-prop-reset-changes.d.ts +10 -0
  68. package/dist/components/Timeline/get-sequence-prop-reset-changes.js +33 -0
  69. package/dist/components/Timeline/reset-selected-timeline-props.js +2 -8
  70. package/dist/components/Timeline/save-sequence-prop.d.ts +12 -1
  71. package/dist/components/Timeline/save-sequence-prop.js +25 -1
  72. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  73. package/dist/components/Timeline/use-timeline-asset-drop.js +4 -0
  74. package/dist/components/UndoRedoButtons.js +15 -6
  75. package/dist/components/handle-drop.d.ts +3 -2
  76. package/dist/components/handle-drop.js +2 -1
  77. package/dist/components/import-assets.d.ts +4 -2
  78. package/dist/components/import-assets.js +20 -7
  79. package/dist/components/use-element-overwrite-confirmation.d.ts +2 -0
  80. package/dist/components/use-element-overwrite-confirmation.js +73 -0
  81. package/dist/components/use-static-files.js +7 -2
  82. package/dist/error-overlay/react-overlay/effects/resolve-file-source.js +13 -2
  83. package/dist/esm/{chunk-dr1y1vm3.js → chunk-n1kj09yv.js} +7634 -6308
  84. package/dist/esm/index.mjs +24 -8
  85. package/dist/esm/internals.mjs +7634 -6308
  86. package/dist/esm/previewEntry.mjs +7646 -6320
  87. package/dist/esm/renderEntry.mjs +1 -1
  88. package/dist/helpers/browser-studio-operations.d.ts +3 -0
  89. package/dist/helpers/browser-studio-operations.js +14 -0
  90. package/dist/helpers/client-id.d.ts +0 -1
  91. package/dist/helpers/client-id.js +15 -10
  92. package/dist/helpers/download-blob.d.ts +1 -0
  93. package/dist/helpers/download-blob.js +15 -0
  94. package/dist/helpers/inject-css.js +5 -3
  95. package/dist/helpers/open-in-editor.js +26 -5
  96. package/dist/helpers/preview-server-events.js +46 -9
  97. package/dist/helpers/use-create-composition.js +8 -6
  98. package/dist/helpers/use-menu-structure.js +29 -0
  99. package/dist/hot-middleware-client/client.js +3 -3
  100. package/dist/icons/border-radius.d.ts +4 -0
  101. package/dist/icons/border-radius.js +8 -0
  102. package/dist/icons/fullscreen.d.ts +4 -0
  103. package/dist/icons/fullscreen.js +6 -0
  104. package/dist/previewEntry.js +1 -1
  105. package/dist/state/modals.d.ts +4 -0
  106. package/dist/state/timeline-sequence-hover.d.ts +17 -0
  107. package/dist/state/timeline-sequence-hover.js +33 -0
  108. package/package.json +13 -12
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
7
7
  const frame_1 = require("../../icons/frame");
8
8
  const solid_1 = require("../../icons/solid");
9
+ const video_1 = require("../../icons/video");
9
10
  const VisualControls_1 = require("../../visual-controls/VisualControls");
10
11
  const DefaultPropsEditor_1 = require("../DefaultPropsEditor");
11
12
  const get_zod_if_possible_1 = require("../get-zod-if-possible");
@@ -26,11 +27,12 @@ const actionIconStyle = {
26
27
  width: 18,
27
28
  };
28
29
  const CompositionActions = ({ readOnlyStudio }) => {
29
- const { canInsertAsset, canInsertSolid, canShowInsertAsset, canShowInsertSolid, insertAsset, insertSolid, } = (0, use_composition_actions_1.useCompositionActions)();
30
- if (readOnlyStudio || (!canShowInsertAsset && !canShowInsertSolid)) {
30
+ const { canInsertAsset, canInsertComposition, canInsertSolid, canShowInsertAsset, canShowInsertComposition, canShowInsertSolid, insertAsset, insertComposition, insertSolid, } = (0, use_composition_actions_1.useCompositionActions)();
31
+ if ((readOnlyStudio && !canShowInsertSolid) ||
32
+ (!canShowInsertAsset && !canShowInsertComposition && !canShowInsertSolid)) {
31
33
  return null;
32
34
  }
33
- return (jsx_runtime_1.jsxs(common_1.InspectorActionSection, { children: [canShowInsertSolid ? (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: !canInsertSolid, onClick: insertSolid, renderIcon: (color) => (jsx_runtime_1.jsx(solid_1.SolidIcon, { color: color, style: actionIconStyle })), children: "Add Solid" })) : null, canShowInsertAsset ? (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: !canInsertAsset, onClick: insertAsset, renderIcon: (color) => (jsx_runtime_1.jsx(frame_1.PicIcon, { color: color, style: actionIconStyle })), children: "Add asset..." })) : null] }));
35
+ return (jsx_runtime_1.jsxs(common_1.InspectorActionSection, { children: [canShowInsertSolid ? (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: !canInsertSolid, onClick: insertSolid, renderIcon: (color) => (jsx_runtime_1.jsx(solid_1.SolidIcon, { color: color, style: actionIconStyle })), children: "Add Solid" })) : null, canShowInsertAsset ? (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: !canInsertAsset, onClick: insertAsset, renderIcon: (color) => (jsx_runtime_1.jsx(frame_1.PicIcon, { color: color, style: actionIconStyle })), children: "Add asset..." })) : null, canShowInsertComposition ? (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: !canInsertComposition, onClick: insertComposition, renderIcon: (color) => (jsx_runtime_1.jsx(video_1.FilmIcon, { color: color, style: actionIconStyle })), children: "Add composition..." })) : null] }));
34
36
  };
35
37
  const CompositionDefaultPropsSection = ({ composition, currentDefaultProps, readOnlyStudio, setDefaultProps }) => {
36
38
  var _a;
@@ -2,4 +2,5 @@ import React from 'react';
2
2
  import type { TimelineSelection } from '../Timeline/TimelineSelection';
3
3
  export declare const SelectedInspector: React.FC<{
4
4
  readonly selection: TimelineSelection;
5
+ readonly readOnlyStudio: boolean;
5
6
  }>;
@@ -8,9 +8,9 @@ const GuideInspector_1 = require("./GuideInspector");
8
8
  const inspector_selection_1 = require("./inspector-selection");
9
9
  const KeyframeInspector_1 = require("./KeyframeInspector");
10
10
  const SequenceSelectionInspector_1 = require("./SequenceSelectionInspector");
11
- const SelectedInspector = ({ selection }) => {
11
+ const SelectedInspector = ({ selection, readOnlyStudio }) => {
12
12
  if ((0, inspector_selection_1.isSequenceSectionSelection)(selection)) {
13
- return jsx_runtime_1.jsx(SequenceSelectionInspector_1.SequenceSelectionInspector, { selection: selection });
13
+ return (jsx_runtime_1.jsx(SequenceSelectionInspector_1.SequenceSelectionInspector, { selection: selection, readOnlyStudio: readOnlyStudio }));
14
14
  }
15
15
  if (selection.type === 'keyframe') {
16
16
  return jsx_runtime_1.jsx(KeyframeInspector_1.KeyframeInspector, { selection: selection });
@@ -2,4 +2,5 @@ import React from 'react';
2
2
  import type { SequenceSectionSelection } from './inspector-selection';
3
3
  export declare const SequenceSelectionInspector: React.FC<{
4
4
  readonly selection: SequenceSectionSelection;
5
+ readonly readOnlyStudio: boolean;
5
6
  }>;
@@ -99,7 +99,7 @@ const SequenceSourceActions = ({ selection, track, validatedSource }) => {
99
99
  }, [confirm, selection.nodePathInfo, sourceActionsDisabled]);
100
100
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [(freezeFrameMenuItem === null || freezeFrameMenuItem === void 0 ? void 0 : freezeFrameMenuItem.type) === 'item' ? (jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: Boolean(freezeFrameMenuItem.disabled), onClick: () => freezeFrameMenuItem.onClick(freezeFrameMenuItem.id, null), renderIcon: (color) => (jsx_runtime_1.jsx(snowflake_1.SnowflakeIcon, { style: largeActionIconStyle, color: color })), children: freezeFrameMenuItem.label })) : null, jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: sourceActionsDisabled, onClick: onDuplicate, renderIcon: (color) => (jsx_runtime_1.jsx(duplicate_1.DuplicateIcon, { style: largeActionIconStyle, color: color })), children: "Duplicate" }), jsx_runtime_1.jsx(common_1.InspectorInlineAction, { disabled: sourceActionsDisabled, onClick: onDelete, renderIcon: (color) => (jsx_runtime_1.jsx(trash_1.TrashIcon, { style: actionIconStyle, color: color })), children: "Delete" })] }));
101
101
  };
102
- const SequenceExpandedInspector = ({ track }) => {
102
+ const SequenceExpandedInspector = ({ track, readOnlyStudio }) => {
103
103
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
104
104
  const { selectedItems, selectItems } = (0, TimelineSelection_1.useTimelineSelection)();
105
105
  const sourceLocation = (0, SequenceInspectorHeader_1.useSequenceInspectorSourceLocation)(track.sequence);
@@ -143,17 +143,17 @@ const SequenceExpandedInspector = ({ track }) => {
143
143
  return (jsx_runtime_1.jsxs("div", { style: styles_1.selectedContainer, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, onPointerDown: selectSequenceOnInspectorPointerDown, children: [
144
144
  jsx_runtime_1.jsx(SequenceInspectorHeader_1.SequenceInspectorHeader, { sourceLocation: sourceLocation, track: track }), connectedCompositions.length > 0 ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
145
145
  jsx_runtime_1.jsx(common_1.InspectorSectionDivider, {}), jsx_runtime_1.jsx(ConnectedCompositionsSection_1.ConnectedCompositionsSection, { connectedCompositions: connectedCompositions })
146
- ] })) : null, validatedLocation ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx(InspectorSequenceSection_1.InspectorSequenceSection, { sequence: track.sequence, validatedLocation: validatedLocation, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, renderTransformControls: () => jsx_runtime_1.jsx(AlignmentControls_1.AlignmentControls, { track: track }) }), jsx_runtime_1.jsxs(common_1.InspectorActionSection, { children: [
146
+ ] })) : null, validatedLocation ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx(InspectorSequenceSection_1.InspectorSequenceSection, { sequence: track.sequence, readOnlyStudio: readOnlyStudio, validatedLocation: validatedLocation, nodePathInfo: track.nodePathInfo, keyframeDisplayOffset: track.keyframeDisplayOffset, renderTransformControls: () => jsx_runtime_1.jsx(AlignmentControls_1.AlignmentControls, { track: track }) }), jsx_runtime_1.jsxs(common_1.InspectorActionSection, { children: [
147
147
  jsx_runtime_1.jsx(SplitSequenceAction, { selection: sequenceSelection, track: track }), jsx_runtime_1.jsx(SequenceSourceActions, { selection: sequenceSelection, track: track, validatedSource: validatedLocation.source })
148
148
  ] })
149
149
  ] })) : (jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Source controls unavailable" }))] }));
150
150
  };
151
- const SequenceSelectionInspector = ({ selection }) => {
151
+ const SequenceSelectionInspector = ({ selection, readOnlyStudio }) => {
152
152
  const track = (0, use_track_for_selection_1.useTrackForSelection)(selection);
153
153
  if (!track) {
154
154
  return jsx_runtime_1.jsx(common_1.InspectorMessage, { children: "Sequence inspector unavailable" });
155
155
  }
156
156
  const stackKey = track.sequence.getStack();
157
- return (jsx_runtime_1.jsx(SequenceExpandedInspector, { track: track }, stackKey !== null && stackKey !== void 0 ? stackKey : track.sequence.id));
157
+ return (jsx_runtime_1.jsx(SequenceExpandedInspector, { track: track, readOnlyStudio: readOnlyStudio }, stackKey !== null && stackKey !== void 0 ? stackKey : track.sequence.id));
158
158
  };
159
159
  exports.SequenceSelectionInspector = SequenceSelectionInspector;
@@ -0,0 +1,22 @@
1
+ import type { SchemaFieldGroup } from '@remotion/studio-shared';
2
+ import { type InteractivitySchema } from 'remotion';
3
+ export type SmartCollapsibleInspectorGroup = Extract<SchemaFieldGroup, 'background' | 'border' | 'border-radius' | 'crop' | 'layout'>;
4
+ export type InspectorSectionActivity = 'active' | 'inactive' | 'unknown';
5
+ type InspectorSectionPropStatus = {
6
+ readonly status: 'static';
7
+ readonly codeValue: unknown;
8
+ } | {
9
+ readonly status: 'computed' | 'keyframed';
10
+ };
11
+ export declare const isSmartCollapsibleInspectorGroup: (group: SchemaFieldGroup) => group is SmartCollapsibleInspectorGroup;
12
+ export declare const isInspectorSectionEffectivelyInactive: ({ group, propStatuses, schema, }: {
13
+ readonly group: SmartCollapsibleInspectorGroup;
14
+ readonly propStatuses: Readonly<Record<string, InspectorSectionPropStatus>> | undefined;
15
+ readonly schema?: InteractivitySchema | undefined;
16
+ }) => boolean;
17
+ export declare const getInspectorSectionActivity: ({ group, propStatuses, schema, }: {
18
+ readonly group: SmartCollapsibleInspectorGroup;
19
+ readonly propStatuses: Readonly<Record<string, InspectorSectionPropStatus>> | undefined;
20
+ readonly schema?: InteractivitySchema | undefined;
21
+ }) => InspectorSectionActivity;
22
+ export {};
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInspectorSectionActivity = exports.isInspectorSectionEffectivelyInactive = exports.isSmartCollapsibleInspectorGroup = void 0;
4
+ const remotion_1 = require("remotion");
5
+ const color_conversion_1 = require("../../helpers/color-conversion");
6
+ const BORDER_KEYS = [
7
+ 'style.borderWidth',
8
+ 'style.borderStyle',
9
+ 'style.borderColor',
10
+ ];
11
+ const BORDER_RADIUS_SHORTHAND_KEY = 'style.borderRadius';
12
+ const BORDER_RADIUS_LONGHAND_KEYS = [
13
+ 'style.borderTopLeftRadius',
14
+ 'style.borderTopRightRadius',
15
+ 'style.borderBottomRightRadius',
16
+ 'style.borderBottomLeftRadius',
17
+ ];
18
+ const CROP_KEYS = ['cropLeft', 'cropRight', 'cropTop', 'cropBottom'];
19
+ const LAYOUT_KEYS = ['layout', 'premountFor'];
20
+ const BACKGROUND_COLOR_KEY = 'style.backgroundColor';
21
+ const isSmartCollapsibleInspectorGroup = (group) => {
22
+ return (group === 'background' ||
23
+ group === 'border' ||
24
+ group === 'border-radius' ||
25
+ group === 'crop' ||
26
+ group === 'layout');
27
+ };
28
+ exports.isSmartCollapsibleInspectorGroup = isSmartCollapsibleInspectorGroup;
29
+ const getStaticValue = ({ key, propStatuses, }) => {
30
+ const status = propStatuses === null || propStatuses === void 0 ? void 0 : propStatuses[key];
31
+ if ((status === null || status === void 0 ? void 0 : status.status) !== 'static') {
32
+ return { found: false };
33
+ }
34
+ return { found: true, value: status.codeValue };
35
+ };
36
+ const isZeroOrUndefined = (value) => {
37
+ return value === undefined || value === 0;
38
+ };
39
+ const isTransparentOrUndefined = (value) => {
40
+ if (value === undefined) {
41
+ return true;
42
+ }
43
+ if (typeof value !== 'string') {
44
+ return false;
45
+ }
46
+ return (0, color_conversion_1.parseAnyColor)(value).a === 0;
47
+ };
48
+ const hasOnlyStaticZeroValues = ({ keys, propStatuses, }) => {
49
+ for (const key of keys) {
50
+ const result = getStaticValue({ key, propStatuses });
51
+ if (!result.found || !isZeroOrUndefined(result.value)) {
52
+ return false;
53
+ }
54
+ }
55
+ return true;
56
+ };
57
+ const isBorderInactive = (propStatuses) => {
58
+ const [width, style, color] = BORDER_KEYS.map((key) => getStaticValue({ key, propStatuses }));
59
+ if (!width.found || !style.found || !color.found) {
60
+ return false;
61
+ }
62
+ if (style.value === undefined ||
63
+ style.value === 'none' ||
64
+ style.value === 'hidden') {
65
+ return true;
66
+ }
67
+ if (width.value === 0) {
68
+ return true;
69
+ }
70
+ return isTransparentOrUndefined(color.value) && color.value !== undefined;
71
+ };
72
+ const isBorderRadiusInactive = (propStatuses) => {
73
+ const shorthandStatus = propStatuses === null || propStatuses === void 0 ? void 0 : propStatuses[BORDER_RADIUS_SHORTHAND_KEY];
74
+ if (shorthandStatus && shorthandStatus.status !== 'static') {
75
+ return false;
76
+ }
77
+ if ((shorthandStatus === null || shorthandStatus === void 0 ? void 0 : shorthandStatus.codeValue) !== undefined) {
78
+ return shorthandStatus.codeValue === 0;
79
+ }
80
+ return hasOnlyStaticZeroValues({
81
+ keys: BORDER_RADIUS_LONGHAND_KEYS,
82
+ propStatuses,
83
+ });
84
+ };
85
+ const isLayoutInactive = ({ propStatuses, schema, }) => {
86
+ if (!schema) {
87
+ return false;
88
+ }
89
+ const flatSchema = remotion_1.Internals.getFlatSchemaWithAllKeys(schema);
90
+ const layoutKeys = LAYOUT_KEYS.filter((key) => flatSchema[key] !== undefined);
91
+ if (layoutKeys.length === 0) {
92
+ return false;
93
+ }
94
+ return layoutKeys.every((key) => {
95
+ const result = getStaticValue({ key, propStatuses });
96
+ const field = flatSchema[key];
97
+ if (!result.found || !field || field.type === 'hidden') {
98
+ return false;
99
+ }
100
+ const effectiveValue = result.value === undefined ? field.default : result.value;
101
+ return Object.is(effectiveValue, field.default);
102
+ });
103
+ };
104
+ const isInspectorSectionEffectivelyInactive = ({ group, propStatuses, schema, }) => {
105
+ if (group === 'layout') {
106
+ return isLayoutInactive({ propStatuses, schema });
107
+ }
108
+ if (group === 'border') {
109
+ return isBorderInactive(propStatuses);
110
+ }
111
+ if (group === 'border-radius') {
112
+ return isBorderRadiusInactive(propStatuses);
113
+ }
114
+ if (group === 'crop') {
115
+ return hasOnlyStaticZeroValues({ keys: CROP_KEYS, propStatuses });
116
+ }
117
+ const backgroundColor = getStaticValue({
118
+ key: BACKGROUND_COLOR_KEY,
119
+ propStatuses,
120
+ });
121
+ return (backgroundColor.found && isTransparentOrUndefined(backgroundColor.value));
122
+ };
123
+ exports.isInspectorSectionEffectivelyInactive = isInspectorSectionEffectivelyInactive;
124
+ const hasOwnStatus = ({ key, propStatuses, }) => {
125
+ return (propStatuses !== undefined &&
126
+ Object.prototype.hasOwnProperty.call(propStatuses, key));
127
+ };
128
+ const hasEveryStatus = ({ keys, propStatuses, }) => {
129
+ return keys.every((key) => hasOwnStatus({ key, propStatuses }));
130
+ };
131
+ const getInspectorSectionActivity = ({ group, propStatuses, schema, }) => {
132
+ let resolved = false;
133
+ if (group === 'border') {
134
+ resolved = hasEveryStatus({ keys: BORDER_KEYS, propStatuses });
135
+ }
136
+ else if (group === 'border-radius') {
137
+ const shorthandStatus = propStatuses === null || propStatuses === void 0 ? void 0 : propStatuses[BORDER_RADIUS_SHORTHAND_KEY];
138
+ resolved =
139
+ (shorthandStatus !== undefined &&
140
+ (shorthandStatus.status !== 'static' ||
141
+ shorthandStatus.codeValue !== undefined)) ||
142
+ hasEveryStatus({ keys: BORDER_RADIUS_LONGHAND_KEYS, propStatuses });
143
+ }
144
+ else if (group === 'crop') {
145
+ resolved = hasEveryStatus({ keys: CROP_KEYS, propStatuses });
146
+ }
147
+ else if (group === 'layout') {
148
+ const flatSchema = schema
149
+ ? remotion_1.Internals.getFlatSchemaWithAllKeys(schema)
150
+ : undefined;
151
+ const layoutKeys = LAYOUT_KEYS.filter((key) => (flatSchema === null || flatSchema === void 0 ? void 0 : flatSchema[key]) !== undefined);
152
+ resolved =
153
+ layoutKeys.length > 0 && hasEveryStatus({ keys: layoutKeys, propStatuses });
154
+ }
155
+ else {
156
+ resolved = hasOwnStatus({ key: BACKGROUND_COLOR_KEY, propStatuses });
157
+ }
158
+ if (!resolved) {
159
+ return 'unknown';
160
+ }
161
+ return (0, exports.isInspectorSectionEffectivelyInactive)({ group, propStatuses, schema })
162
+ ? 'inactive'
163
+ : 'active';
164
+ };
165
+ exports.getInspectorSectionActivity = getInspectorSectionActivity;
@@ -39,9 +39,11 @@ exports.sequenceHeaderDivider = {
39
39
  };
40
40
  exports.sectionHeader = {
41
41
  color: colors_1.LIGHT_TEXT,
42
+ fontFamily: 'sans-serif',
42
43
  fontSize: 12,
43
44
  fontWeight: 'bold',
44
- padding: `8px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
45
+ lineHeight: '24px',
46
+ padding: `4px ${InspectorPanelLayout_1.INSPECTOR_PANEL_HORIZONTAL_PADDING}px`,
45
47
  userSelect: 'none',
46
48
  };
47
49
  exports.inspectorSectionBody = {
@@ -76,11 +78,15 @@ exports.sectionHeaderRow = {
76
78
  minWidth: 0,
77
79
  };
78
80
  exports.sectionHeaderTitle = {
81
+ alignItems: 'center',
79
82
  color: colors_1.LIGHT_TEXT,
83
+ display: 'flex',
80
84
  flexShrink: 0,
85
+ fontFamily: 'sans-serif',
81
86
  fontSize: 12,
82
87
  fontWeight: 'bold',
83
88
  lineHeight: '16px',
89
+ minHeight: 24,
84
90
  minWidth: 0,
85
91
  overflow: 'hidden',
86
92
  textOverflow: 'ellipsis',
@@ -1,8 +1,11 @@
1
1
  export declare const useCompositionActions: () => {
2
2
  canInsertAsset: boolean;
3
+ canInsertComposition: boolean;
3
4
  canInsertSolid: boolean;
4
5
  canShowInsertAsset: boolean;
6
+ canShowInsertComposition: boolean;
5
7
  canShowInsertSolid: boolean;
6
8
  insertAsset: () => Promise<void>;
9
+ insertComposition: () => void;
7
10
  insertSolid: () => Promise<void>;
8
11
  };
@@ -1,14 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCompositionActions = void 0;
4
+ const drag_and_drop_1 = require("@remotion/drag-and-drop");
4
5
  const react_1 = require("react");
5
6
  const remotion_1 = require("remotion");
7
+ const browser_studio_operations_1 = require("../../helpers/browser-studio-operations");
6
8
  const client_id_1 = require("../../helpers/client-id");
7
9
  const interactivity_enabled_1 = require("../../helpers/interactivity-enabled");
8
10
  const open_in_editor_1 = require("../../helpers/open-in-editor");
11
+ const modals_1 = require("../../state/modals");
9
12
  const call_api_1 = require("../call-api");
10
13
  const import_assets_1 = require("../import-assets");
11
14
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
15
+ const get_stack_1 = require("../Timeline/TimelineStack/get-stack");
12
16
  const use_resolved_stack_1 = require("../Timeline/use-resolved-stack");
13
17
  const useCompositionActions = () => {
14
18
  var _a, _b;
@@ -16,9 +20,13 @@ const useCompositionActions = () => {
16
20
  const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
17
21
  const [isAddingSolid, setIsAddingSolid] = (0, react_1.useState)(false);
18
22
  const [isAddingAsset, setIsAddingAsset] = (0, react_1.useState)(false);
23
+ const [isAddingComposition, setIsAddingComposition] = (0, react_1.useState)(false);
24
+ const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
19
25
  const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
20
26
  const previewConnected = previewServerState.type === 'connected';
21
27
  const previewInteractive = previewConnected && (0, interactivity_enabled_1.isStudioInteractivityEnabled)();
28
+ const browserStudioOperations = (0, browser_studio_operations_1.getBrowserStudioOperations)();
29
+ const browserStudioCanInsertSolid = browserStudioOperations !== null;
22
30
  const currentCompositionId = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
23
31
  const currentComposition = (0, react_1.useMemo)(() => {
24
32
  var _a;
@@ -28,13 +36,15 @@ const useCompositionActions = () => {
28
36
  return ((_a = compositions.find((composition) => composition.id === currentCompositionId)) !== null && _a !== void 0 ? _a : null);
29
37
  }, [compositions, currentCompositionId]);
30
38
  const resolvedCompositionLocation = (0, use_resolved_stack_1.useResolvedStack)((_a = currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.stack) !== null && _a !== void 0 ? _a : null);
31
- const compositionFile = (_b = resolvedCompositionLocation === null || resolvedCompositionLocation === void 0 ? void 0 : resolvedCompositionLocation.source) !== null && _b !== void 0 ? _b : null;
39
+ const compositionFile = (_b = resolvedCompositionLocation === null || resolvedCompositionLocation === void 0 ? void 0 : resolvedCompositionLocation.source) !== null && _b !== void 0 ? _b : (currentCompositionId && browserStudioOperations
40
+ ? browserStudioOperations.getCompositionFile(currentCompositionId)
41
+ : null);
32
42
  const compositionComponentInfo = (0, open_in_editor_1.useCachedCompositionComponentInfo)({
33
43
  compositionFile,
34
44
  compositionId: currentCompositionId,
35
45
  });
36
- const canShowInsertSolid = previewInteractive &&
37
- !window.remotion_isReadOnlyStudio &&
46
+ const canShowInsertSolid = (previewInteractive || browserStudioCanInsertSolid) &&
47
+ (!window.remotion_isReadOnlyStudio || browserStudioCanInsertSolid) &&
38
48
  (compositionComponentInfo === null || compositionComponentInfo === void 0 ? void 0 : compositionComponentInfo.canAddSequence) === true &&
39
49
  currentCompositionId !== null &&
40
50
  compositionFile !== null &&
@@ -46,6 +56,8 @@ const useCompositionActions = () => {
46
56
  currentCompositionId !== null &&
47
57
  compositionFile !== null;
48
58
  const canInsertAsset = canShowInsertAsset && !isAddingAsset;
59
+ const canShowInsertComposition = canShowInsertAsset;
60
+ const canInsertComposition = canShowInsertComposition && !isAddingComposition;
49
61
  const insertSolid = (0, react_1.useCallback)(async () => {
50
62
  if (!canInsertSolid ||
51
63
  currentCompositionId === null ||
@@ -55,7 +67,7 @@ const useCompositionActions = () => {
55
67
  }
56
68
  setIsAddingSolid(true);
57
69
  try {
58
- const result = await (0, call_api_1.callApi)('/api/insert-jsx-element', {
70
+ const request = {
59
71
  compositionFile,
60
72
  compositionId: currentCompositionId,
61
73
  from: null,
@@ -65,7 +77,10 @@ const useCompositionActions = () => {
65
77
  height: videoConfig.height,
66
78
  position: null,
67
79
  },
68
- });
80
+ };
81
+ const result = browserStudioOperations
82
+ ? await browserStudioOperations.insertSolid(request)
83
+ : await (0, call_api_1.callApi)('/api/insert-jsx-element', request);
69
84
  if (result.success) {
70
85
  (0, NotificationCenter_1.showNotification)('Added <Solid> to source file', 2000);
71
86
  return;
@@ -78,7 +93,13 @@ const useCompositionActions = () => {
78
93
  finally {
79
94
  setIsAddingSolid(false);
80
95
  }
81
- }, [canInsertSolid, compositionFile, currentCompositionId, videoConfig]);
96
+ }, [
97
+ browserStudioOperations,
98
+ canInsertSolid,
99
+ compositionFile,
100
+ currentCompositionId,
101
+ videoConfig,
102
+ ]);
82
103
  const insertAsset = (0, react_1.useCallback)(async () => {
83
104
  if (!canInsertAsset ||
84
105
  currentCompositionId === null ||
@@ -107,12 +128,76 @@ const useCompositionActions = () => {
107
128
  setIsAddingAsset(false);
108
129
  }
109
130
  }, [canInsertAsset, compositionFile, currentCompositionId, videoConfig]);
131
+ const onCompositionSelected = (0, react_1.useCallback)(async (composition) => {
132
+ var _a, _b, _c, _d, _e;
133
+ if (!canInsertComposition ||
134
+ currentCompositionId === null ||
135
+ compositionFile === null) {
136
+ return;
137
+ }
138
+ setIsAddingComposition(true);
139
+ try {
140
+ const resolvedLocation = composition.stack
141
+ ? await (0, get_stack_1.getOriginalLocationFromStack)(composition.stack, 'sequence')
142
+ : null;
143
+ const selectedCompositionFile = (_b = (_a = resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source) !== null && _a !== void 0 ? _a : browserStudioOperations === null || browserStudioOperations === void 0 ? void 0 : browserStudioOperations.getCompositionFile(composition.id)) !== null && _b !== void 0 ? _b : null;
144
+ const compositionDragData = drag_and_drop_1.DragAndDropInternals.makeDragData({
145
+ type: 'composition',
146
+ compositionFile: selectedCompositionFile,
147
+ compositionId: composition.id,
148
+ width: (_c = composition.width) !== null && _c !== void 0 ? _c : null,
149
+ height: (_d = composition.height) !== null && _d !== void 0 ? _d : null,
150
+ durationInFrames: (_e = composition.durationInFrames) !== null && _e !== void 0 ? _e : null,
151
+ }).data;
152
+ await (0, import_assets_1.insertComposition)({
153
+ composition: compositionDragData,
154
+ compositionFile,
155
+ compositionId: currentCompositionId,
156
+ dropPosition: null,
157
+ from: null,
158
+ });
159
+ }
160
+ catch (error) {
161
+ (0, NotificationCenter_1.showNotification)(`Could not add composition: ${error instanceof Error ? error.message : String(error)}`, 4000);
162
+ }
163
+ finally {
164
+ setIsAddingComposition(false);
165
+ }
166
+ }, [
167
+ browserStudioOperations,
168
+ canInsertComposition,
169
+ compositionFile,
170
+ currentCompositionId,
171
+ ]);
172
+ const insertComposition = (0, react_1.useCallback)(() => {
173
+ if (!canInsertComposition) {
174
+ return;
175
+ }
176
+ setSelectedModal({
177
+ type: 'quick-switcher',
178
+ mode: 'compositions',
179
+ invocationTimestamp: Date.now(),
180
+ assetSelection: null,
181
+ compositionSelection: {
182
+ excludeCompositionId: currentCompositionId,
183
+ onSelected: onCompositionSelected,
184
+ },
185
+ });
186
+ }, [
187
+ canInsertComposition,
188
+ currentCompositionId,
189
+ onCompositionSelected,
190
+ setSelectedModal,
191
+ ]);
110
192
  return {
111
193
  canInsertAsset,
194
+ canInsertComposition,
112
195
  canInsertSolid,
113
196
  canShowInsertAsset,
197
+ canShowInsertComposition,
114
198
  canShowInsertSolid,
115
199
  insertAsset,
200
+ insertComposition,
116
201
  insertSolid,
117
202
  };
118
203
  };
@@ -26,10 +26,10 @@ const InspectorPanel = ({ composition, currentDefaultProps, readOnlyStudio, setD
26
26
  }
27
27
  if (selectedItems.length > 1) {
28
28
  if (sameSequenceInspectorSelection) {
29
- return (jsx_runtime_1.jsx("div", { style: styles_1.container, children: jsx_runtime_1.jsx(SelectedInspector_1.SelectedInspector, { selection: sameSequenceInspectorSelection }) }));
29
+ return (jsx_runtime_1.jsx("div", { style: styles_1.container, children: jsx_runtime_1.jsx(SelectedInspector_1.SelectedInspector, { selection: sameSequenceInspectorSelection, readOnlyStudio: readOnlyStudio }) }));
30
30
  }
31
31
  return (jsx_runtime_1.jsx("div", { style: styles_1.container, children: jsx_runtime_1.jsxs(common_1.InspectorMessage, { children: [selectedItems.length, " items selected"] }) }));
32
32
  }
33
- return (jsx_runtime_1.jsx("div", { style: styles_1.container, children: jsx_runtime_1.jsx(SelectedInspector_1.SelectedInspector, { selection: selectedItems[0] }) }));
33
+ return (jsx_runtime_1.jsx("div", { style: styles_1.container, children: jsx_runtime_1.jsx(SelectedInspector_1.SelectedInspector, { selection: selectedItems[0], readOnlyStudio: readOnlyStudio }) }));
34
34
  };
35
35
  exports.InspectorPanel = InspectorPanel;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { TSequence } from 'remotion';
2
+ import { type TSequence } 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 FlatTreeRow } from '../helpers/timeline-layout';
@@ -11,6 +11,7 @@ export declare const getInspectorSelectableItems: (rows: readonly FlatTreeRow[])
11
11
  export declare const hasSequenceControls: (sequence: TSequence) => sequence is SequenceWithControls;
12
12
  export declare const InspectorSequenceSection: React.FC<{
13
13
  readonly sequence: SequenceWithControls;
14
+ readonly readOnlyStudio: boolean;
14
15
  readonly validatedLocation: CodePosition;
15
16
  readonly nodePathInfo: SequenceNodePathInfo;
16
17
  readonly keyframeDisplayOffset: number;