跳转到内容

Hooks ​

PowerPointViewer 是精简的 forwardRef 协调组件,绝大部分逻辑由 PowerPointViewer.tsx 中组合的 80 多个自定义 hook 实现,视觉组件主要负责展示。状态完全保存在 React hooks 中,没有外部状态库。

公共与内部接口

大部分 hook 属于内部架构,依赖特定组合顺序和共享输入。经过筛选的小部分从 pptx-react-viewer/viewer 导出,遵循正常的语义化版本兼容保证。完整集合可从 pptx-react-viewer/internals 导入,但内部构建块不受该保证约束,应优先使用稳定导出。详见完整 Hooks 参考。

内部架构 ​

下表说明组件内部如何连接。虽然这些 hook 可以导入,但它们依赖特定组合顺序和输入,应将此表视为架构说明,而非 API 契约。

Hook职责
useViewerState组合核心状态和 UI 状态。
useViewerCoreState幻灯片、选择、画布尺寸和模式等文档状态。
useViewerUIState面板可见性、对话框和工具栏标记。
useDerivedSlideState计算可见索引、节和母版伪幻灯片。
useEditorHistory撤销重做快照栈,在指针交互期间延迟捕获。
useZoomViewport缩放、适应宽度和视口 DOM ref。
useEditorOperations将全部编辑操作组合为一个结果。
useLoadContent挂载时通过 PptxHandler 解析 PPTX 缓冲区。
useContentLifecycle内容同步、未保存修改跟踪和恢复检测。
usePresentationMode放映导航、动画和切换。
useExportHandlersPNG、SVG、PDF、GIF、视频和 PPTX 导出。
usePrintHandlers打印对话框和布局。
useInsertElements插入形状、图片、文本框、表格和图表。
useElementManipulation移动、缩放、旋转和删除元素。
useSlideManagement添加、删除、复制、重排和隐藏幻灯片。
useTableOperations插入和删除行列,合并和拆分单元格。
usePointerHandlers处理画布的鼠标和触控事件。
useKeyboardShortcuts定义快捷键。
useViewerIntegration顶层整合 I/O、导出、打印、指针和生命周期。

此外还有剪贴板、批注、节、自动保存、字体注入、恢复、主题和放映子 hook 等数十项。按职责分组的完整列表见完整 Hooks 参考。

内部 hooks 通常需要连接大量状态。例如 useEditorHistory 接收完整编辑状态和 8 个状态 setter,返回 { canUndo, canRedo, undoLabel, redoLabel, handleUndo, handleRedo, resetHistory, markDirty, buildHistorySnapshot }。这种结构适合组件内部组合;独立实现撤销重做时,可以直接修改 PptxData 并保存快照,详见编程编辑。

公共 hooks ​

以下 hooks 从 pptx-react-viewer/viewer 导出,可安全按需使用并支持 tree-shaking。根入口 pptx-react-viewer 导出组件、renderToCanvas、主题工具(包括 useViewerTheme)和偏好设置工具,但不导出下列预览器 hooks。

tsx
import { useThemeSwitching, useCollaborativeState } from 'pptx-react-viewer/viewer';

useThemeSwitching ​

切换已加载文档本身的 PowerPoint 主题,即 OOXML 颜色和字体方案,不是组件界面主题,两者区别见主题配置。它使用手动加载得到的同一组 PptxHandler 和 PptxData。

ts
interface UseThemeSwitchingInput {
	handlerRef: RefObject<PptxHandler | null>;
	data: PptxData | null;
	onDataChange: (newData: PptxData) => void;
	onThemeChanged?: (preset: PptxThemePreset) => void;
}

interface ThemeSwitchingResult {
	presets: readonly PptxThemePreset[]; // built-in presets (office, facet, ion, ...)
	switchToPreset: (preset: PptxThemePreset) => Promise<void>;
	switchToCustom: (
		colorScheme: PptxThemeColorScheme,
		fontScheme?: PptxThemeFontScheme,
		themeName?: string,
	) => Promise<void>;
	currentPreset: PptxThemePreset | undefined; // preset matching the current theme, if any
}

switchToPreset 同时更新内存中的 ZIP 和解析数据中已求值的元素颜色,使修改在 save() 后仍保留。

tsx
function ThemePicker({ handlerRef, data, setData }: Props) {
	const { presets, switchToPreset, currentPreset } = useThemeSwitching({
		handlerRef,
		data,
		onDataChange: setData,
	});

	return (
		<div>
			{presets.map((preset) => (
				<button
					key={preset.id}
					onClick={() => switchToPreset(preset)}
					aria-pressed={preset.id === currentPreset?.id}
				>
					{preset.name}
				</button>
			))}
		</div>
	);
}

协作 hooks ​

用于自定义协作界面或自行控制同步,详见协作。需要可选依赖 yjs 和 y-websocket,它们动态加载,未使用时可被 tree-shaking 移除。各 hook 使用与组件 collaboration 属性相同的 CollaborationConfig,包括 roomId、serverUrl、userName,以及可选的 transport('websocket' | 'webrtc')、signaling、userColor、userAvatar、authToken、role、sessionIntent,和写入者使用的 onWriteBack、writeBackDebounceMs。

Hook签名(输入 => 结果)
useYjsProvider{ config?: CollaborationConfig } => { status, awareness, doc, clientId, synced, retry }
usePresenceTracking{ awareness, localClientId, userName, userColor, userAvatar?, role?, canvasWidth, canvasHeight } => { remoteUsers, broadcastPresence }
useCollaborativeState{ config?, canvasWidth, canvasHeight } => CollaborationContextValue | null
useCollaborativeHistory{ localClientId, handleUndo, handleRedo, canUndo, canRedo } => 包装后的相同四项,仅对本地修改执行撤销

useCollaborativeState 是内置 CollaborationProvider 的组合入口,管理传输层 useYjsProvider 和在线状态 usePresenceTracking。config 为 undefined 时返回 null,hooks 保持休眠,组件树结构保持稳定。

tsx
import { useCollaborativeState } from 'pptx-react-viewer/viewer';

function PresenceBar({ roomId, userName }: { roomId: string; userName: string }) {
	const collab = useCollaborativeState({
		config: { roomId, serverUrl: 'wss://collab.example.com', userName },
		canvasWidth: 960,
		canvasHeight: 540,
	});

	if (!collab) return null;
	return (
		<span>{collab.status === 'connected' ? `${collab.connectedCount} online` : collab.status}</span>
	);
}

useYjsProvider 是轻量传输层,延迟导入 Yjs 包,创建 Y.Doc 和 Provider。连接失败超时后进入 status: 'error',可通过 retry() 恢复。它还提供 synced,让后加入的用户等房间文档到达后再允许本地写入。

同时导出的还有 CollaborationProvider、RemoteUserCursors、UserAvatarBar 和 CollaborationStatusIndicator。

观众窗口工具 ​

以下工具不是 hooks,但从 pptx-react-viewer/viewer 导出,用于演讲者和观众窗口之间的流程:isAudienceTab、loadAudienceContent、storeAudienceContent、clearAudienceContent 和 parseAudienceNonce。

直接使用内部 hook ​

公共 hooks 无法满足需求时,可以从 pptx-react-viewer/internals 导入全部内部 hook:

tsx
import { useEditorHistory, useViewerState } from 'pptx-react-viewer/internals';

内部构建块

pptx-react-viewer/internals 原样导出组件内部使用的 hooks,不受语义化版本兼容保证约束。签名、行为、名称乃至是否存在,都可能在不升级主版本的情况下改变。请优先使用属性、句柄或 /viewer 的公共 hooks,仅在高级接入需要时使用内部入口,并锁定精确版本。

完整列表见完整 Hooks 参考,整体结构见组件概览。

基于 Apache-2.0 许可证发布