Merge pull request #2126 from heygen-com/studio-flat-07-retire-legacy-style-grade

fix(studio): retire legacy Style and Grade sections from flat inspector
This commit is contained in:
Vance Ingalls
2026-07-14 16:04:31 -07:00
committed by GitHub
2 changed files with 41 additions and 35 deletions
@@ -692,6 +692,45 @@ describe("PropertyPanel — Grade group (flag on)", () => {
},
RENDER_TIMEOUT_MS,
);
it(
"does not render the legacy Style/Grade Section duplicates for a style-and-grade-editable element",
async () => {
// A <video> with no text fields is both style-editable (inherited
// capabilities.canEditStyles: true) and grade-editable (tag === "video"),
// so both the flat Style and Grade groups render — the exact shape that
// used to also mount the legacy ColorGradingSection + StyleSections below
// them (the hybrid-duplication bug this task retires).
const { host, root } = await renderPanel(true, {
...baseElement(),
tagName: "video",
textFields: [],
});
expect(host.textContent).toContain("Style");
expect(host.textContent).toContain("Grade");
// The legacy `Section` primitive (propertyPanelStyleSections.tsx /
// propertyPanelColorGradingSection.tsx) renders a `<section
// data-panel-section="<slugified-title>">` for each of its sections. A
// bare textContent check can't tell a legacy Section title apart from a
// flat row label with the same word — "Fill" is both the legacy Fill
// `Section` title AND a row label inside FlatStyleSection, which is
// supposed to still be there — so assert on the legacy Section's actual
// DOM shape instead of a substring match.
for (const slug of [
"radius",
"stroke",
"effects",
"clip",
"transparency",
"fill",
"color-grading",
]) {
expect(host.querySelector(`[data-panel-section="${slug}"]`)).toBeNull();
}
act(() => root.unmount());
},
RENDER_TIMEOUT_MS,
);
});
describe("PropertyPanel — Media group (Plan 4)", () => {
@@ -14,9 +14,8 @@ import { FlatMotionSection } from "./propertyPanelFlatMotionSection";
import { FlatMediaSection } from "./propertyPanelFlatMediaSection";
import { deriveElementTiming } from "./propertyPanelFlatTimingDerivation";
import { createGsapLivePreview } from "./gsapLivePreview";
import { formatTextFieldPreview, StyleSections } from "./propertyPanelSections";
import { formatTextFieldPreview } from "./propertyPanelSections";
import { STUDIO_GSAP_PANEL_ENABLED } from "./manualEditingAvailability";
import { ColorGradingSection } from "./propertyPanelColorGradingSection";
import { useColorGradingController } from "./useColorGradingController";
import { usePersistedPinnedGroups } from "../../hooks/usePersistedPinnedGroups";
import {
@@ -55,8 +54,7 @@ const EMPTY_GSAP_EFFECT_HANDLERS = {
* (same one-directional-import precedent as FlatTextSection). Rendered only
* when STUDIO_FLAT_INSPECTOR_ENABLED is on; owns the one-open/pin group state.
*
* The Text/Style/Layout/Motion/Media groups share the one-open accordion. The
* legacy Color-Grading section renders unchanged below the flat groups.
* The Text/Style/Layout/Motion/Media/Grade groups share the one-open accordion.
*/
// fallow-ignore-next-line complexity
export function PropertyPanelFlat({
@@ -502,37 +500,6 @@ export function PropertyPanelFlat({
{g.content}
</FlatGroup>
))}
{sections.colorGrading && (
<ColorGradingSection
key={[
element.id ?? "",
element.hfId ?? "",
element.selector ?? "",
String(element.selectorIndex ?? ""),
].join("|")}
projectId={projectId}
element={element}
assets={assets}
previewIframeRef={previewIframeRef}
onImportAssets={onImportAssets}
onSetAttributeLive={onSetAttributeLive}
onApplyScope={onApplyColorGradingScope}
/>
)}
{showEditableSections && (
<StyleSections
projectId={projectId}
element={element}
styles={styles}
assets={assets}
onSetStyle={onSetStyle}
onImportAssets={onImportAssets}
gsapBorderRadius={gsapBorderRadius}
// Flex now lives in the flat Layout group (LayoutFlexBlock); suppress
// the legacy StyleSections Flex `Section` so it renders exactly once.
hideFlex
/>
)}
</div>
<PropertyPanelFlatFooter
onAskAgent={onAskAgent}