/**
* Variables tab section for compositions OTHER than the active one. A variable
* promoted into a sub-comp lives in that frame's file, not the active session —
* this surfaces every such file's declarations grouped by path, with per-file
* management (edit declaration / remove). Live-preview override for these is a
* follow-up (values are per-composition-scope), so no preview control is shown.
*/
import { useCallback, useState, type MutableRefObject } from "react";
import type { Composition, CompositionVariable } from "@hyperframes/sdk";
import {
useEditVariablesInFile,
useProjectCompositionVariables,
type CompositionVariableGroup,
type RecordEditFn,
} from "../../hooks/useProjectCompositionVariables";
import {
DeclarationForm,
draftFromDeclaration,
mergeDeclarationEdit,
} from "./VariablesDeclarationForm";
import { RowAction } from "./VariablesRowAction";
function CompositionSection({
group,
editingKey,
onToggleEdit,
onSave,
onRemove,
}: {
group: CompositionVariableGroup;
editingKey: string | null;
onToggleEdit: (key: string | null) => void;
onSave: (path: string, decl: CompositionVariable) => void;
onRemove: (path: string, id: string) => void;
}) {
return (
{group.path}
{group.variables.map((decl) => {
const key = `${group.path}::${decl.id}`;
const editing = editingKey === key;
return (
{decl.label}
{decl.type}
onToggleEdit(editing ? null : key)}
/>
onRemove(group.path, decl.id)}
/>
{decl.description &&
{decl.description}
}
{editing && (
onSave(group.path, mergeDeclarationEdit(decl, edited))}
onCancel={() => onToggleEdit(null)}
/>
)}
);
})}
);
}
export function VariablesOtherCompositions({
fileTree,
excludePath,
refreshKey,
readProjectFile,
writeProjectFile,
recordEdit,
reloadPreview,
domEditSaveTimestampRef,
}: {
fileTree: string[];
excludePath: string;
refreshKey: unknown;
readProjectFile: (path: string) => Promise;
writeProjectFile: (path: string, content: string) => Promise;
recordEdit: RecordEditFn;
reloadPreview: () => void;
domEditSaveTimestampRef: MutableRefObject;
}) {
const [selfRefresh, setSelfRefresh] = useState(0);
const groups = useProjectCompositionVariables(
fileTree,
excludePath,
readProjectFile,
`${refreshKey}:${selfRefresh}`,
);
const editInFile = useEditVariablesInFile({
readProjectFile,
writeProjectFile,
recordEdit,
reloadPreview,
domEditSaveTimestampRef,
});
const [editingKey, setEditingKey] = useState(null);
const onSave = useCallback(
(path: string, decl: CompositionVariable) => {
setEditingKey(null);
void editInFile(path, `Update variable "${decl.id}"`, (s: Composition) =>
s.updateVariableDeclaration(decl.id, decl),
).then(() => setSelfRefresh((r) => r + 1));
},
[editInFile],
);
const onRemove = useCallback(
(path: string, id: string) => {
void editInFile(path, `Remove variable "${id}"`, (s: Composition) =>
s.removeVariableDeclaration(id),
).then(() => setSelfRefresh((r) => r + 1));
},
[editInFile],
);
if (groups.length === 0) return null;
return (
Other compositions
{groups.map((group) => (
))}
);
}