Files
wehub-resource-sync c48612c494
CI / E2E Tests (push) Has been cancelled
CI / Lint, Typecheck & Unit Tests (push) Has been cancelled
Docs Build / Build docs site (push) Has been cancelled
Publish @openmaic packages / Build, validate & publish (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:23 +08:00

73 lines
2.7 KiB
TypeScript

'use client';
import { ElementTypes, type PPTElement } from '@openmaic/dsl';
import { useMemo } from 'react';
import { BaseImageElement } from '../components/element/ImageElement/BaseImageElement';
import { BaseTextElement } from '../components/element/TextElement/BaseTextElement';
import { BaseShapeElement } from '../components/element/ShapeElement/BaseShapeElement';
import { BaseLineElement } from '../components/element/LineElement/BaseLineElement';
import { BaseChartElement } from '../components/element/ChartElement/BaseChartElement';
import { BaseLatexElement } from '../components/element/LatexElement/BaseLatexElement';
import { BaseTableElement } from '../components/element/TableElement/BaseTableElement';
import { BaseVideoElement } from '../components/element/VideoElement/BaseVideoElement';
import { BaseCodeElement } from '../components/element/CodeElement/BaseCodeElement';
import { useSceneSelector } from '@/lib/contexts/scene-context';
import type { SceneContent } from '@/lib/types/stage';
interface ScreenElementProps {
readonly elementInfo: PPTElement;
readonly elementIndex: number;
readonly animate?: boolean;
}
export function ScreenElement({ elementInfo, elementIndex, animate }: ScreenElementProps) {
const CurrentElementComponent = useMemo(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- element components have varying prop signatures
const elementTypeMap: Record<string, any> = {
[ElementTypes.IMAGE]: BaseImageElement,
[ElementTypes.TEXT]: BaseTextElement,
[ElementTypes.SHAPE]: BaseShapeElement,
[ElementTypes.LINE]: BaseLineElement,
[ElementTypes.CHART]: BaseChartElement,
[ElementTypes.LATEX]: BaseLatexElement,
[ElementTypes.TABLE]: BaseTableElement,
[ElementTypes.VIDEO]: BaseVideoElement,
[ElementTypes.CODE]: BaseCodeElement,
// TODO: Add other element types
// [ElementTypes.AUDIO]: BaseAudioElement,
};
return elementTypeMap[elementInfo.type] || null;
}, [elementInfo.type]);
const theme = useSceneSelector<SceneContent, { fontColor: string; fontName: string }>(
(content) => {
if (content.type === 'slide') {
return content.canvas.theme;
}
return {
fontColor: '#333333',
fontName: 'Microsoft YaHei',
};
},
);
if (!CurrentElementComponent) {
return null;
}
return (
<div
className="screen-element"
id={`screen-element-${elementInfo.id}`}
style={{
zIndex: elementIndex,
color: theme.fontColor,
fontFamily: theme.fontName,
}}
>
<CurrentElementComponent elementInfo={elementInfo} animate={animate} />
</div>
);
}