pptx-react-viewer 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/{AiChatPanel-UXPHPUQV.mjs → AiChatPanel-6W6ZBAGU.mjs} +4 -4
  3. package/dist/AiChatPanel-6W6ZBAGU.mjs.br +0 -0
  4. package/dist/AiChatPanel-6W6ZBAGU.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-GTCK35EI.js → AiChatPanel-MALC32TM.js} +23 -23
  6. package/dist/AiChatPanel-MALC32TM.js.br +0 -0
  7. package/dist/AiChatPanel-MALC32TM.js.gz +0 -0
  8. package/dist/{Model3DScene-HDUHTKPF.mjs → Model3DScene-57HZ4NVD.mjs} +1 -1
  9. package/dist/Model3DScene-57HZ4NVD.mjs.br +0 -0
  10. package/dist/Model3DScene-57HZ4NVD.mjs.gz +0 -0
  11. package/dist/{Model3DScene-USPBP3KE.js → Model3DScene-76R2YXSO.js} +2 -2
  12. package/dist/Model3DScene-76R2YXSO.js.br +0 -0
  13. package/dist/Model3DScene-76R2YXSO.js.gz +0 -0
  14. package/dist/{SurfaceChart3DScene-NZ3K5CC6.js → SurfaceChart3DScene-2QZZTBV4.js} +2 -2
  15. package/dist/SurfaceChart3DScene-2QZZTBV4.js.br +0 -0
  16. package/dist/SurfaceChart3DScene-2QZZTBV4.js.gz +0 -0
  17. package/dist/{SurfaceChart3DScene-7SLM73XC.mjs → SurfaceChart3DScene-JGOQNHSU.mjs} +1 -1
  18. package/dist/{SurfaceChart3DScene-7SLM73XC.mjs.br → SurfaceChart3DScene-JGOQNHSU.mjs.br} +0 -0
  19. package/dist/SurfaceChart3DScene-JGOQNHSU.mjs.gz +0 -0
  20. package/dist/{chunk-25VSL2BB.js → chunk-2JDWFMIK.js} +259 -17
  21. package/dist/chunk-2JDWFMIK.js.br +0 -0
  22. package/dist/chunk-2JDWFMIK.js.gz +0 -0
  23. package/dist/{chunk-SMW4QYGK.js → chunk-34BUZNKO.js} +370 -364
  24. package/dist/chunk-34BUZNKO.js.br +0 -0
  25. package/dist/chunk-34BUZNKO.js.gz +0 -0
  26. package/dist/{chunk-OIH753PJ.mjs → chunk-4FO4JMTN.mjs} +98 -160
  27. package/dist/chunk-4FO4JMTN.mjs.br +0 -0
  28. package/dist/chunk-4FO4JMTN.mjs.gz +0 -0
  29. package/dist/{chunk-PVCUYPU7.mjs → chunk-6OLS3EJW.mjs} +1 -1
  30. package/dist/chunk-6OLS3EJW.mjs.br +0 -0
  31. package/dist/chunk-6OLS3EJW.mjs.gz +0 -0
  32. package/dist/{chunk-SOBKYMMR.js → chunk-6UXRNLHD.js} +5418 -3133
  33. package/dist/chunk-6UXRNLHD.js.br +0 -0
  34. package/dist/chunk-6UXRNLHD.js.gz +0 -0
  35. package/dist/{chunk-Z6HIZWIQ.mjs → chunk-CD434OFE.mjs} +259 -17
  36. package/dist/chunk-CD434OFE.mjs.br +0 -0
  37. package/dist/chunk-CD434OFE.mjs.gz +0 -0
  38. package/dist/{chunk-KGXDCDA5.js → chunk-D6SHCB4V.js} +410 -472
  39. package/dist/chunk-D6SHCB4V.js.br +0 -0
  40. package/dist/chunk-D6SHCB4V.js.gz +0 -0
  41. package/dist/{chunk-MZJMOEEX.js → chunk-IKISUZKE.js} +2575 -816
  42. package/dist/chunk-IKISUZKE.js.br +0 -0
  43. package/dist/chunk-IKISUZKE.js.gz +0 -0
  44. package/dist/{chunk-AHPZGUL7.mjs → chunk-JPTO6P5K.mjs} +135 -130
  45. package/dist/chunk-JPTO6P5K.mjs.br +0 -0
  46. package/dist/chunk-JPTO6P5K.mjs.gz +0 -0
  47. package/dist/{chunk-VH2QF5CT.mjs → chunk-L47Y62L6.mjs} +2511 -809
  48. package/dist/chunk-L47Y62L6.mjs.br +0 -0
  49. package/dist/chunk-L47Y62L6.mjs.gz +0 -0
  50. package/dist/{chunk-TJ5QMUUJ.mjs → chunk-NQLVK23T.mjs} +3847 -1562
  51. package/dist/chunk-NQLVK23T.mjs.br +0 -0
  52. package/dist/chunk-NQLVK23T.mjs.gz +0 -0
  53. package/dist/{chunk-VFLBLJ4G.js → chunk-YEM2VOAP.js} +3 -3
  54. package/dist/chunk-YEM2VOAP.js.br +0 -0
  55. package/dist/chunk-YEM2VOAP.js.gz +0 -0
  56. package/dist/i18n.js +4 -4
  57. package/dist/i18n.js.br +0 -0
  58. package/dist/i18n.js.gz +0 -0
  59. package/dist/i18n.mjs +1 -1
  60. package/dist/i18n.mjs.br +0 -0
  61. package/dist/i18n.mjs.gz +0 -0
  62. package/dist/index.d.ts +34 -0
  63. package/dist/index.js +36 -36
  64. package/dist/index.js.br +0 -0
  65. package/dist/index.js.gz +0 -0
  66. package/dist/index.mjs +6 -6
  67. package/dist/index.mjs.br +0 -0
  68. package/dist/index.mjs.gz +0 -0
  69. package/dist/internals.d.ts +44 -1
  70. package/dist/internals.d.ts.map +1 -1
  71. package/dist/internals.js +79 -79
  72. package/dist/internals.js.br +0 -0
  73. package/dist/internals.js.gz +0 -0
  74. package/dist/internals.mjs +4 -4
  75. package/dist/internals.mjs.br +0 -0
  76. package/dist/internals.mjs.gz +0 -0
  77. package/dist/pptx-viewer.css +1 -1
  78. package/dist/pptx-viewer.css.br +0 -0
  79. package/dist/pptx-viewer.css.gz +0 -0
  80. package/dist/{useViewerBuildingBlocks-DMDZRawe.d.ts → useViewerBuildingBlocks-C59NY1qZ.d.ts} +15 -2
  81. package/dist/useViewerBuildingBlocks-C59NY1qZ.d.ts.map +1 -0
  82. package/dist/viewer/index.d.ts +21 -0
  83. package/dist/viewer/index.js +22 -22
  84. package/dist/viewer/index.js.br +0 -0
  85. package/dist/viewer/index.js.gz +0 -0
  86. package/dist/viewer/index.mjs +6 -6
  87. package/dist/viewer/index.mjs.br +0 -0
  88. package/dist/viewer/index.mjs.gz +0 -0
  89. package/package.json +1 -1
  90. package/dist/AiChatPanel-GTCK35EI.js.br +0 -0
  91. package/dist/AiChatPanel-GTCK35EI.js.gz +0 -0
  92. package/dist/AiChatPanel-UXPHPUQV.mjs.br +0 -0
  93. package/dist/AiChatPanel-UXPHPUQV.mjs.gz +0 -0
  94. package/dist/Model3DScene-HDUHTKPF.mjs.br +0 -0
  95. package/dist/Model3DScene-HDUHTKPF.mjs.gz +0 -0
  96. package/dist/Model3DScene-USPBP3KE.js.br +0 -0
  97. package/dist/Model3DScene-USPBP3KE.js.gz +0 -0
  98. package/dist/SurfaceChart3DScene-7SLM73XC.mjs.gz +0 -0
  99. package/dist/SurfaceChart3DScene-NZ3K5CC6.js.br +0 -0
  100. package/dist/SurfaceChart3DScene-NZ3K5CC6.js.gz +0 -0
  101. package/dist/chunk-25VSL2BB.js.br +0 -0
  102. package/dist/chunk-25VSL2BB.js.gz +0 -0
  103. package/dist/chunk-AHPZGUL7.mjs.br +0 -0
  104. package/dist/chunk-AHPZGUL7.mjs.gz +0 -0
  105. package/dist/chunk-KGXDCDA5.js.br +0 -0
  106. package/dist/chunk-KGXDCDA5.js.gz +0 -0
  107. package/dist/chunk-MZJMOEEX.js.br +0 -0
  108. package/dist/chunk-MZJMOEEX.js.gz +0 -0
  109. package/dist/chunk-OIH753PJ.mjs.br +0 -0
  110. package/dist/chunk-OIH753PJ.mjs.gz +0 -0
  111. package/dist/chunk-PVCUYPU7.mjs.br +0 -0
  112. package/dist/chunk-PVCUYPU7.mjs.gz +0 -0
  113. package/dist/chunk-SMW4QYGK.js.br +0 -0
  114. package/dist/chunk-SMW4QYGK.js.gz +0 -0
  115. package/dist/chunk-SOBKYMMR.js.br +0 -0
  116. package/dist/chunk-SOBKYMMR.js.gz +0 -0
  117. package/dist/chunk-TJ5QMUUJ.mjs.br +0 -0
  118. package/dist/chunk-TJ5QMUUJ.mjs.gz +0 -0
  119. package/dist/chunk-VFLBLJ4G.js.br +0 -0
  120. package/dist/chunk-VFLBLJ4G.js.gz +0 -0
  121. package/dist/chunk-VH2QF5CT.mjs.br +0 -0
  122. package/dist/chunk-VH2QF5CT.mjs.gz +0 -0
  123. package/dist/chunk-Z6HIZWIQ.mjs.br +0 -0
  124. package/dist/chunk-Z6HIZWIQ.mjs.gz +0 -0
  125. package/dist/useViewerBuildingBlocks-DMDZRawe.d.ts.map +0 -1
Binary file
Binary file
@@ -1,6 +1,6 @@
1
- import { cloneHistorySnapshot, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, partitionTemplateElements, UNGROUPED_SECTION_ID, stopAllPersistentAudio, buildSaveSlides, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, EMU_PER_PX, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-AHPZGUL7.mjs';
2
- import { translationsEn } from './chunk-Z6HIZWIQ.mjs';
3
- import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, PresentationAnimationController, computeEntranceAnimationDelay, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, buildMorphTransitionPlan, morphOptionToMode, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, buildInitialGuides, EncryptedFileError, saveAutosaveSnapshot, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, downloadBlob, sanitizeDownloadFilename, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, detectTouchDevice, detectOrientation, isMobileViewport, MOBILE_BREAKPOINT, TABLET_BREAKPOINT, mayLeaveSlideShow, remapTextToSegments, guidePxToEmu, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, createViewerOptionsStore, readSlidesFromYDoc, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, createTouchGestureRecognizer, isKeyboardOpen, openPptxFile, readBackstageRecentFile, isActionHidden, buildElementClipboardPayload, generatePackageReadme, groupElements, generateElementId, makeCloneId, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, derivePresenceList, mapPresentationKey, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildThemeColorMap, reResolveSlideColors, createPresentationSessionId, resolveTransitionDurationMs, isUrlSafe, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, presenterElapsed, stepPresenterZoom, resetPresenterTimer, togglePresenterTimer, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, groupSlidesBySection, hasCopyableFormat, createBackstagePresentation, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, buildSmartArtPresetData, computeSnapToShape, publishLiveGeometry, computeMarqueeHitIds, mergeAdditiveSelection, applyResize, snapBoxToGrid } from './chunk-VH2QF5CT.mjs';
1
+ import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, partitionTemplateElements, UNGROUPED_SECTION_ID, stopAllPersistentAudio, buildSaveSlides, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, executeMediaCommand, buildPdfFromImageData, buildNotesPdf, EMU_PER_PX, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-JPTO6P5K.mjs';
2
+ import { translationsEn } from './chunk-CD434OFE.mjs';
3
+ import { TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, clampZoomScale, zoomInScale, zoomOutScale, PresentationAnimationController, computeEntranceAnimationDelay, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, buildMorphTransitionPlan, morphOptionToMode, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, buildInitialGuides, EncryptedFileError, saveAutosaveSnapshot, isTemplateElementId, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, downloadBlob, sanitizeDownloadFilename, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, detectTouchDevice, detectOrientation, isMobileViewport, MOBILE_BREAKPOINT, TABLET_BREAKPOINT, mayLeaveSlideShow, remapTextToSegments, guidePxToEmu, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, openPptxFile, readBackstageRecentFile, isActionHidden, buildElementClipboardPayload, generatePackageReadme, groupElements, generateElementId, makeCloneId, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, derivePresenceList, mapPresentationKey, buildPrintDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildThemeColorMap, reResolveSlideColors, createPresentationSessionId, resolveTransitionDurationMs, isUrlSafe, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, presenterElapsed, stepPresenterZoom, resetPresenterTimer, togglePresenterTimer, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, groupSlidesBySection, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, buildPrintHtmlDocument, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, safeOpenUrl, ACTION_BUTTON_PRESETS, elementActionToPptxAction, buildSmartArtPresetData, computeSnapToShape, publishLiveGeometry, computeMarqueeHitIds, mergeAdditiveSelection, applyResize, snapBoxToGrid } from './chunk-L47Y62L6.mjs';
4
4
  import { useRef, useState, useEffect, useCallback, useMemo, useSyncExternalStore, useImperativeHandle } from 'react';
5
5
  import JSZip from 'jszip';
6
6
  import { useTranslation } from 'react-i18next';
@@ -743,7 +743,7 @@ function useZoomViewport({
743
743
  if (!wrapper || !canvasViewport) {
744
744
  return;
745
745
  }
746
- const boundedScale = Math.min(Math.max(nextScale, MIN_ZOOM_SCALE), MAX_ZOOM_SCALE);
746
+ const boundedScale = clampZoomScale(nextScale);
747
747
  const nextEditorScale = fitScale * boundedScale;
748
748
  const centerX = (bounds.minX + bounds.maxX) / 2;
749
749
  const centerY = (bounds.minY + bounds.maxY) / 2;
@@ -758,10 +758,10 @@ function useZoomViewport({
758
758
  [fitScale]
759
759
  );
760
760
  const handleZoomIn = useCallback(() => {
761
- setScale((currentScale) => Math.min(currentScale + 0.1, MAX_ZOOM_SCALE));
761
+ setScale((currentScale) => zoomInScale(currentScale));
762
762
  }, []);
763
763
  const handleZoomOut = useCallback(() => {
764
- setScale((currentScale) => Math.max(currentScale - 0.1, MIN_ZOOM_SCALE));
764
+ setScale((currentScale) => zoomOutScale(currentScale));
765
765
  }, []);
766
766
  const handleResetZoom = useCallback(() => {
767
767
  setScale(1);
@@ -802,10 +802,7 @@ function useZoomViewport({
802
802
  availableHeight / boundsHeight
803
803
  );
804
804
  const safeFitScale = fitScale > Number.EPSILON ? fitScale : Number.EPSILON;
805
- const nextScale = Math.min(
806
- Math.max(targetEditorScale / safeFitScale, MIN_ZOOM_SCALE),
807
- MAX_ZOOM_SCALE
808
- );
805
+ const nextScale = clampZoomScale(targetEditorScale / safeFitScale);
809
806
  setScale(nextScale);
810
807
  window.requestAnimationFrame(() => {
811
808
  window.requestAnimationFrame(() => {
@@ -825,9 +822,7 @@ function useZoomViewport({
825
822
  }
826
823
  event.preventDefault();
827
824
  const delta = event.deltaY * -1e-3;
828
- setScale(
829
- (currentScale) => Math.min(Math.max(currentScale + delta, MIN_ZOOM_SCALE), MAX_ZOOM_SCALE)
830
- );
825
+ setScale((currentScale) => clampZoomScale(currentScale + delta));
831
826
  }, []);
832
827
  useEffect(() => {
833
828
  const viewport = canvasViewportRef.current;
@@ -3592,6 +3587,7 @@ function useViewerUIState() {
3592
3587
  const [spellCheckEnabled, setSpellCheckEnabled] = useState(true);
3593
3588
  const [showGrid, setShowGrid] = useState(false);
3594
3589
  const [showRulers, setShowRulers] = useState(false);
3590
+ const [showGuides, setShowGuides] = useState(true);
3595
3591
  const [snapToGrid, setSnapToGrid] = useState(true);
3596
3592
  const [snapToShape, setSnapToShape] = useState(true);
3597
3593
  const [guides, setGuides] = useState(
@@ -3645,6 +3641,8 @@ function useViewerUIState() {
3645
3641
  setShowGrid,
3646
3642
  showRulers,
3647
3643
  setShowRulers,
3644
+ showGuides,
3645
+ setShowGuides,
3648
3646
  snapToGrid,
3649
3647
  setSnapToGrid,
3650
3648
  snapToShape,
@@ -4710,6 +4708,9 @@ function usePointerHandlers(input) {
4710
4708
  input
4711
4709
  ]);
4712
4710
  }
4711
+ function mouseDownStartsSelectionDrag(event) {
4712
+ return !event.shiftKey && !event.metaKey;
4713
+ }
4713
4714
  function useCanvasInteractions(input) {
4714
4715
  const {
4715
4716
  mode,
@@ -4822,6 +4823,9 @@ function useCanvasInteractions(input) {
4822
4823
  if (inlineEditingElementId && inlineEditingElementId !== elementId) {
4823
4824
  handleInlineEditCommit();
4824
4825
  }
4826
+ if (!mouseDownStartsSelectionDrag(e)) {
4827
+ return;
4828
+ }
4825
4829
  const wasSelected = selectedElementIdSet.has(elementId);
4826
4830
  if (!wasSelected) {
4827
4831
  ops.applySelection(elementId);
@@ -9269,140 +9273,77 @@ function useContentLifecycle(input) {
9269
9273
  });
9270
9274
  return { handlerRef, serializeSlides, autosaveStatus };
9271
9275
  }
9272
- var NUDGE_SMALL = 2;
9273
- var NUDGE_LARGE = 20;
9274
9276
  function useKeyboardShortcuts(input) {
9275
9277
  const inputRef = useRef(input);
9276
9278
  inputRef.current = input;
9277
9279
  const handleKeyDown = useCallback((e) => {
9278
- const {
9279
- mode,
9280
- canEdit,
9281
- inlineEditingElementId,
9282
- tableEditorState,
9283
- activeTool,
9284
- hasSelection,
9285
- onDelete,
9286
- onCopy,
9287
- onCut,
9288
- onPaste,
9289
- onDuplicate,
9290
- onUndo,
9291
- onRedo,
9292
- onSelectAll,
9293
- onEscape,
9294
- onNudge,
9295
- onPrevSlide,
9296
- onNextSlide
9297
- } = inputRef.current;
9298
- if (mode !== "edit" || !canEdit) {
9299
- return;
9300
- }
9301
- const target = e.target;
9302
- const isTextInput = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.isContentEditable;
9303
- if (e.key === "Escape") {
9304
- e.preventDefault();
9305
- onEscape();
9306
- return;
9307
- }
9308
- if (inlineEditingElementId || tableEditorState?.isEditing || activeTool !== "select") {
9309
- return;
9310
- }
9311
- if (isTextInput) {
9312
- return;
9313
- }
9314
- const isMod = e.metaKey || e.ctrlKey;
9315
- if ((e.key === "Delete" || e.key === "Backspace") && hasSelection) {
9316
- e.preventDefault();
9317
- onDelete();
9318
- return;
9319
- }
9320
- if (isMod) {
9321
- switch (e.key.toLowerCase()) {
9322
- case "z":
9323
- e.preventDefault();
9324
- if (e.shiftKey) {
9325
- onRedo();
9326
- } else {
9327
- onUndo();
9328
- }
9329
- return;
9330
- case "y":
9331
- e.preventDefault();
9332
- onRedo();
9333
- return;
9334
- case "c":
9335
- if (hasSelection) {
9336
- e.preventDefault();
9337
- onCopy();
9338
- }
9339
- return;
9340
- case "x":
9341
- if (hasSelection) {
9342
- e.preventDefault();
9343
- onCut();
9344
- }
9345
- return;
9346
- case "v":
9347
- e.preventDefault();
9348
- onPaste();
9349
- return;
9350
- case "d":
9351
- if (hasSelection) {
9352
- e.preventDefault();
9353
- onDuplicate();
9354
- }
9355
- return;
9356
- case "a":
9357
- e.preventDefault();
9358
- onSelectAll();
9359
- return;
9360
- }
9361
- }
9362
- if (hasSelection && (e.key === "ArrowUp" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowRight")) {
9363
- e.preventDefault();
9364
- const step = e.shiftKey ? NUDGE_LARGE : NUDGE_SMALL;
9365
- let dx = 0;
9366
- let dy = 0;
9367
- switch (e.key) {
9368
- case "ArrowUp":
9369
- dy = -step;
9370
- break;
9371
- case "ArrowDown":
9372
- dy = step;
9373
- break;
9374
- case "ArrowLeft":
9375
- dx = -step;
9376
- break;
9377
- case "ArrowRight":
9378
- dx = step;
9379
- break;
9380
- }
9381
- onNudge(dx, dy);
9280
+ const current = inputRef.current;
9281
+ const { action, dx, dy } = mapEditorKey(e, {
9282
+ canEdit: current.canEdit,
9283
+ isPresenting: current.mode !== "edit",
9284
+ hasSelection: current.hasSelection,
9285
+ isEditingText: Boolean(current.inlineEditingElementId || current.tableEditorState?.isEditing),
9286
+ isDrawing: current.activeTool !== "select",
9287
+ isTextInputTarget: isEditorTextInputTarget(e.target)
9288
+ });
9289
+ if (action === null) {
9382
9290
  return;
9383
9291
  }
9384
- if (!hasSelection && (e.key === "ArrowLeft" || e.key === "ArrowRight")) {
9385
- e.preventDefault();
9386
- if (e.key === "ArrowLeft") {
9387
- onPrevSlide?.();
9388
- } else {
9389
- onNextSlide?.();
9390
- }
9292
+ e.preventDefault();
9293
+ switch (action) {
9294
+ case "escape":
9295
+ current.onEscape();
9296
+ break;
9297
+ case "delete":
9298
+ current.onDelete();
9299
+ break;
9300
+ case "undo":
9301
+ current.onUndo();
9302
+ break;
9303
+ case "redo":
9304
+ current.onRedo();
9305
+ break;
9306
+ case "copy":
9307
+ current.onCopy();
9308
+ break;
9309
+ case "cut":
9310
+ current.onCut();
9311
+ break;
9312
+ case "paste":
9313
+ current.onPaste();
9314
+ break;
9315
+ case "duplicate":
9316
+ current.onDuplicate();
9317
+ break;
9318
+ case "selectAll":
9319
+ current.onSelectAll();
9320
+ break;
9321
+ case "group":
9322
+ current.onGroup?.();
9323
+ break;
9324
+ case "ungroup":
9325
+ current.onUngroup?.();
9326
+ break;
9327
+ case "toggleShortcuts":
9328
+ current.onToggleShortcuts?.();
9329
+ break;
9330
+ case "nudge":
9331
+ current.onNudge(dx ?? 0, dy ?? 0);
9332
+ break;
9333
+ case "prevSlide":
9334
+ current.onPrevSlide?.();
9335
+ break;
9336
+ case "nextSlide":
9337
+ current.onNextSlide?.();
9338
+ break;
9391
9339
  }
9392
9340
  }, []);
9393
9341
  useEffect(() => {
9394
- const container = input.containerRef.current;
9395
- if (container) {
9396
- container.addEventListener("keydown", handleKeyDown);
9397
- }
9398
9342
  window.addEventListener("keydown", handleKeyDown);
9399
9343
  return () => {
9400
- if (container) {
9401
- container.removeEventListener("keydown", handleKeyDown);
9402
- }
9403
9344
  window.removeEventListener("keydown", handleKeyDown);
9404
9345
  };
9405
- }, [input.containerRef, handleKeyDown]);
9346
+ }, [handleKeyDown]);
9406
9347
  }
9407
9348
 
9408
9349
  // src/viewer/hooks/useKeyboardShortcutWiring.ts
@@ -9433,8 +9374,13 @@ function useKeyboardShortcutWiring(input) {
9433
9374
  ops.applySelection(allIds[0], allIds);
9434
9375
  }
9435
9376
  },
9377
+ onGroup: manipulation.handleGroupElements,
9378
+ onUngroup: manipulation.handleUngroupElement,
9379
+ onToggleShortcuts: () => state.setIsShortcutHelpOpen((prev) => !prev),
9436
9380
  onEscape: () => {
9437
- if (state.inlineEditingElementId) {
9381
+ if (state.isShortcutHelpOpen) {
9382
+ state.setIsShortcutHelpOpen(false);
9383
+ } else if (state.inlineEditingElementId) {
9438
9384
  state.setInlineEditingElementId(null);
9439
9385
  state.setInlineEditingText("");
9440
9386
  } else if (state.contextMenuState) {
@@ -9631,7 +9577,7 @@ function useViewerIntegration(input) {
9631
9577
  return zoom.scale;
9632
9578
  },
9633
9579
  setZoom(level) {
9634
- zoom.setScale(Math.min(Math.max(level, MIN_ZOOM_SCALE), MAX_ZOOM_SCALE));
9580
+ zoom.setScale(clampZoomScale(level));
9635
9581
  },
9636
9582
  zoomIn() {
9637
9583
  zoom.handleZoomIn();
@@ -10335,29 +10281,11 @@ function buildCanvasProps(input) {
10335
10281
  } = input;
10336
10282
  const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
10337
10283
  const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
10338
- let slideTitle;
10339
- if (activeSlide) {
10340
- for (const el of activeSlide.elements) {
10341
- const phType = el.placeholderType;
10342
- if (phType === "title" || phType === "ctrTitle") {
10343
- const txt = el.text;
10344
- if (txt) {
10345
- slideTitle = txt;
10346
- break;
10347
- }
10348
- }
10349
- }
10350
- }
10351
- const hf = s.headerFooter;
10352
- const fieldContext = {
10353
- slideNumber: activeSlide?.slideNumber,
10354
- dateTimeText: hf.dateTimeText,
10355
- dateFormat: hf.dateFormat,
10356
- footerText: hf.footerText,
10357
- headerText: hf.headerText,
10358
- slideTitle,
10359
- customProperties: s.customProperties.map((p) => ({ name: p.name, value: p.value }))
10360
- };
10284
+ const fieldContext = buildFieldSubstitutionContext({
10285
+ headerFooter: s.headerFooter,
10286
+ customProperties: s.customProperties,
10287
+ slide: activeSlide
10288
+ });
10361
10289
  const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
10362
10290
  const handleActionClick = (_elementId, action) => {
10363
10291
  if (mode === "present") {
@@ -10401,7 +10329,9 @@ function buildCanvasProps(input) {
10401
10329
  showGrid: s.showGrid,
10402
10330
  gridSpacingPx,
10403
10331
  showRulers: s.showRulers,
10404
- guides: s.guides,
10332
+ // View ▸ Guides hides the overlay without discarding the guides: they are
10333
+ // still snapped to while dragging and still round-trip on save.
10334
+ guides: s.showGuides ? s.guides : [],
10405
10335
  presentationElementStates: mode === "present" ? presentation.presentationElementStates : void 0,
10406
10336
  presentationKeyframesCss: mode === "present" ? presentation.presentationKeyframesCss : void 0,
10407
10337
  onClick: canvasHandlers.handleElementClick,
@@ -10610,6 +10540,7 @@ function buildToolbarProps(input) {
10610
10540
  history
10611
10541
  });
10612
10542
  const scopedLayoutOptions = scopeLayoutOptionsToActiveSlide(s.layoutOptions, activeSlide);
10543
+ const selectionSize = selectedElement === null ? 0 : 1;
10613
10544
  return {
10614
10545
  fileName,
10615
10546
  mode,
@@ -10672,11 +10603,13 @@ function buildToolbarProps(input) {
10672
10603
  spellCheckEnabled: s.spellCheckEnabled,
10673
10604
  showGrid: s.showGrid,
10674
10605
  showRulers: s.showRulers,
10606
+ showGuides: s.showGuides,
10675
10607
  snapToGrid: s.snapToGrid,
10676
10608
  snapToShape: s.snapToShape,
10677
10609
  onSetSpellCheckEnabled: s.setSpellCheckEnabled,
10678
10610
  onSetShowGrid: s.setShowGrid,
10679
10611
  onSetShowRulers: s.setShowRulers,
10612
+ onSetShowGuides: s.setShowGuides,
10680
10613
  onSetSnapToGrid: s.setSnapToGrid,
10681
10614
  onSetSnapToShape: s.setSnapToShape,
10682
10615
  onAddGuide: dialogs.handleAddGuide,
@@ -10689,6 +10622,11 @@ function buildToolbarProps(input) {
10689
10622
  onFlip: manipulation.handleFlip,
10690
10623
  onMoveLayer: manipulation.handleMoveLayer,
10691
10624
  onMoveLayerToEdge: manipulation.handleMoveLayerToEdge,
10625
+ onGroupElements: manipulation.handleGroupElements,
10626
+ onUngroupElement: manipulation.handleUngroupElement,
10627
+ onUpdateElementStyle: ops.updateSelectedShapeStyle,
10628
+ selectedCount: s.selectedElementIds.length > 0 ? s.selectedElementIds.length : selectionSize,
10629
+ onOpenHyperlinkDialog: () => dialogs.setIsHyperlinkDialogOpen(true),
10692
10630
  onDuplicate: manipulation.handleDuplicate,
10693
10631
  onDelete: manipulation.handleDelete,
10694
10632
  onExportPng: exportHandlers.handleExportPng,
Binary file
Binary file
@@ -1,4 +1,4 @@
1
- import { ThemePresets, PptxMarkdownConverter } from './chunk-VH2QF5CT.mjs';
1
+ import { ThemePresets, PptxMarkdownConverter } from './chunk-L47Y62L6.mjs';
2
2
  import { __export } from './chunk-XGB3TDIC.mjs';
3
3
  import * as mcp from 'pptx-viewer-mcp';
4
4
  import * as mcpSchemas from 'pptx-viewer-mcp/schemas';
Binary file
Binary file