mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
feat(studio): wire the flat Grade group into the one-open accordion
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
cc07c84a31
commit
384fe5934a
@@ -668,6 +668,26 @@ function flatGroupTitles(host: HTMLElement): string[] {
|
||||
return [...open, ...collapsed];
|
||||
}
|
||||
|
||||
describe("PropertyPanel — Grade group (flag on)", () => {
|
||||
it(
|
||||
"renders the Grade group with its accessory for a grade-editable (video) element",
|
||||
async () => {
|
||||
const { host, root } = await renderPanel(true, {
|
||||
...baseElement(),
|
||||
tagName: "video",
|
||||
textFields: [],
|
||||
});
|
||||
const gradeCollapsedOrOpen =
|
||||
host.querySelector('[data-flat-group-collapsed="true"]') ||
|
||||
host.querySelector('[data-flat-group-open="true"]');
|
||||
expect(host.textContent).toContain("Grade");
|
||||
expect(gradeCollapsedOrOpen).not.toBeNull();
|
||||
act(() => root.unmount());
|
||||
},
|
||||
RENDER_TIMEOUT_MS,
|
||||
);
|
||||
});
|
||||
|
||||
describe("PropertyPanel — Media group (Plan 4)", () => {
|
||||
it(
|
||||
"renders the flat Media group and not the legacy MediaSection, for a video element",
|
||||
|
||||
@@ -17,6 +17,11 @@ import { createGsapLivePreview } from "./gsapLivePreview";
|
||||
import { formatTextFieldPreview, StyleSections } from "./propertyPanelSections";
|
||||
import { STUDIO_GSAP_PANEL_ENABLED } from "./manualEditingAvailability";
|
||||
import { ColorGradingSection } from "./propertyPanelColorGradingSection";
|
||||
import { useColorGradingController } from "./useColorGradingController";
|
||||
import {
|
||||
FlatColorGradingAccessory,
|
||||
FlatColorGradingSection,
|
||||
} from "./propertyPanelFlatColorGradingSection";
|
||||
|
||||
type EditingSections = ReturnType<typeof resolveEditingSections>;
|
||||
|
||||
@@ -225,6 +230,20 @@ export function PropertyPanelFlat({
|
||||
);
|
||||
const [pinnedGroupIds, setPinnedGroupIds] = useState<string[]>([]);
|
||||
|
||||
// Grade group state. Called unconditionally (React rules-of-hooks) even when
|
||||
// sections.colorGrading is false — unlike the legacy ColorGradingSection,
|
||||
// which is only mounted when the section is active, PropertyPanelFlat is not
|
||||
// remounted per-section so the hook must run every render. Shares one state
|
||||
// object between the group's header accessory (compare/status/reset) and its
|
||||
// body (the FlatColorGradingSection controls).
|
||||
const colorGradingController = useColorGradingController({
|
||||
projectId,
|
||||
element,
|
||||
previewIframeRef,
|
||||
onSetAttributeLive,
|
||||
onApplyScope: onApplyColorGradingScope,
|
||||
});
|
||||
|
||||
const isTextEditable = isTextEditableSelection(element);
|
||||
const elementKind = sections.media ? "media" : element.textFields.length > 0 ? "text" : "other";
|
||||
const toggleOpen = (groupId: string) =>
|
||||
@@ -415,6 +434,30 @@ export function PropertyPanelFlat({
|
||||
/>
|
||||
</FlatGroup>
|
||||
)}
|
||||
{sections.colorGrading && (
|
||||
<FlatGroup
|
||||
title="Grade"
|
||||
isOpen={openGroupId === "grade" || pinnedGroupIds.includes("grade")}
|
||||
isPinned={pinnedGroupIds.includes("grade")}
|
||||
onToggleOpen={() => toggleOpen("grade")}
|
||||
onTogglePin={() => togglePin("grade")}
|
||||
accessory={<FlatColorGradingAccessory state={colorGradingController} />}
|
||||
summary={`${colorGradingController.grading.preset ?? "neutral"} · ${Math.round(colorGradingController.grading.intensity * 100)}%`}
|
||||
>
|
||||
<FlatColorGradingSection
|
||||
grading={colorGradingController.grading}
|
||||
assets={assets}
|
||||
onImportAssets={onImportAssets}
|
||||
onCommitColorGrading={colorGradingController.commitColorGrading}
|
||||
applyScope={colorGradingController.applyScope}
|
||||
applyBusy={colorGradingController.applyBusy}
|
||||
onSetApplyScope={colorGradingController.setApplyScope}
|
||||
onApplyToScope={() => void colorGradingController.applyToScope()}
|
||||
onApplyScopeAvailable={Boolean(onApplyColorGradingScope)}
|
||||
mediaMetadata={colorGradingController.mediaMetadata}
|
||||
/>
|
||||
</FlatGroup>
|
||||
)}
|
||||
{sections.colorGrading && (
|
||||
<ColorGradingSection
|
||||
key={[
|
||||
|
||||
Reference in New Issue
Block a user