From 187a9a3f4598a85f313de902304edd8cd2bc11fe Mon Sep 17 00:00:00 2001 From: Aymeric Rabot Date: Mon, 17 Aug 2026 10:19:12 -0400 Subject: [PATCH] perf(editor): stabilize viewer stage mode sets --- .../viewer/viewer-stage-modes.test.ts | 6 +++++ .../components/viewer/viewer-stage-modes.ts | 25 ++++++++++++++++--- .../src/components/viewer/viewer-stage.tsx | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/editor/src/components/viewer/viewer-stage-modes.test.ts b/packages/editor/src/components/viewer/viewer-stage-modes.test.ts index d90002fde9..4c9e56bac1 100644 --- a/packages/editor/src/components/viewer/viewer-stage-modes.test.ts +++ b/packages/editor/src/components/viewer/viewer-stage-modes.test.ts @@ -13,6 +13,12 @@ describe('viewer stage modes', () => { expect(normalizeViewerStageModes([])).toEqual(['3d']) }) + test('reuses normalized combinations across inline prop arrays', () => { + expect(normalizeViewerStageModes(['split', '3d'])).toBe( + normalizeViewerStageModes(['3d', 'split']), + ) + }) + test('falls back to the first enabled mode', () => { expect(resolveViewerStageMode('split', ['3d', '2d'])).toBe('3d') expect(resolveViewerStageMode(undefined, ['2d', 'split'])).toBe('2d') diff --git a/packages/editor/src/components/viewer/viewer-stage-modes.ts b/packages/editor/src/components/viewer/viewer-stage-modes.ts index baa1432e08..5f5fc129f2 100644 --- a/packages/editor/src/components/viewer/viewer-stage-modes.ts +++ b/packages/editor/src/components/viewer/viewer-stage-modes.ts @@ -2,12 +2,29 @@ export const VIEWER_STAGE_MODES = ['3d', '2d', 'split'] as const export type ViewerStageMode = (typeof VIEWER_STAGE_MODES)[number] +const THREE_D_MODES = ['3d'] as const +const TWO_D_MODES = ['2d'] as const +const SPLIT_MODES = ['split'] as const +const THREE_D_TWO_D_MODES = ['3d', '2d'] as const +const THREE_D_SPLIT_MODES = ['3d', 'split'] as const +const TWO_D_SPLIT_MODES = ['2d', 'split'] as const + export function normalizeViewerStageModes( modes: readonly ViewerStageMode[] | undefined, -): ViewerStageMode[] { - const requested = modes ?? VIEWER_STAGE_MODES - const unique = VIEWER_STAGE_MODES.filter((mode) => requested.includes(mode)) - return unique.length > 0 ? unique : ['3d'] +): readonly ViewerStageMode[] { + if (!modes) return VIEWER_STAGE_MODES + + const has3D = modes.includes('3d') + const has2D = modes.includes('2d') + const hasSplit = modes.includes('split') + + if (has3D && has2D && hasSplit) return VIEWER_STAGE_MODES + if (has3D && has2D) return THREE_D_TWO_D_MODES + if (has3D && hasSplit) return THREE_D_SPLIT_MODES + if (has2D && hasSplit) return TWO_D_SPLIT_MODES + if (has2D) return TWO_D_MODES + if (hasSplit) return SPLIT_MODES + return THREE_D_MODES } export function resolveViewerStageMode( diff --git a/packages/editor/src/components/viewer/viewer-stage.tsx b/packages/editor/src/components/viewer/viewer-stage.tsx index b0d77440b5..d3cc8a03e2 100644 --- a/packages/editor/src/components/viewer/viewer-stage.tsx +++ b/packages/editor/src/components/viewer/viewer-stage.tsx @@ -83,7 +83,7 @@ export function ViewerStage({ synchronizeNavigation = true, threeDClassName, }: ViewerStageProps) { - const enabledModes = useMemo(() => normalizeViewerStageModes(modes), [modes]) + const enabledModes = normalizeViewerStageModes(modes) const [internalMode, setInternalMode] = useState(() => resolveViewerStageMode(defaultMode, enabledModes), )