pptx-react-viewer 2.7.1 → 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 (126) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/{AiChatPanel-YAYQ5KUT.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-SRKOMEW6.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-HYMOPMAM.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-ONKC5Z6A.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-YJFWGG5L.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-B3FK4Q2U.mjs → SurfaceChart3DScene-JGOQNHSU.mjs} +1 -1
  18. package/dist/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-GRW7HM6X.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-IDK6XECR.mjs → chunk-4FO4JMTN.mjs} +103 -172
  27. package/dist/chunk-4FO4JMTN.mjs.br +0 -0
  28. package/dist/chunk-4FO4JMTN.mjs.gz +0 -0
  29. package/dist/{chunk-N7EZIKF4.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-BVK7K74O.js → chunk-6UXRNLHD.js} +5462 -3150
  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-JEIMWRKF.js → chunk-D6SHCB4V.js} +414 -483
  39. package/dist/chunk-D6SHCB4V.js.br +0 -0
  40. package/dist/chunk-D6SHCB4V.js.gz +0 -0
  41. package/dist/{chunk-LYS44KMG.js → chunk-IKISUZKE.js} +2605 -816
  42. package/dist/chunk-IKISUZKE.js.br +0 -0
  43. package/dist/chunk-IKISUZKE.js.gz +0 -0
  44. package/dist/{chunk-HQGLKAIY.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-HEAJOHLJ.mjs → chunk-L47Y62L6.mjs} +2539 -809
  48. package/dist/chunk-L47Y62L6.mjs.br +0 -0
  49. package/dist/chunk-L47Y62L6.mjs.gz +0 -0
  50. package/dist/{chunk-2UCJYJUS.mjs → chunk-NQLVK23T.mjs} +4120 -1808
  51. package/dist/chunk-NQLVK23T.mjs.br +0 -0
  52. package/dist/chunk-NQLVK23T.mjs.gz +0 -0
  53. package/dist/{chunk-JVE7BZ25.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-SRKOMEW6.js.br +0 -0
  91. package/dist/AiChatPanel-SRKOMEW6.js.gz +0 -0
  92. package/dist/AiChatPanel-YAYQ5KUT.mjs.br +0 -0
  93. package/dist/AiChatPanel-YAYQ5KUT.mjs.gz +0 -0
  94. package/dist/Model3DScene-HYMOPMAM.mjs.br +0 -0
  95. package/dist/Model3DScene-HYMOPMAM.mjs.gz +0 -0
  96. package/dist/Model3DScene-ONKC5Z6A.js.br +0 -0
  97. package/dist/Model3DScene-ONKC5Z6A.js.gz +0 -0
  98. package/dist/SurfaceChart3DScene-B3FK4Q2U.mjs.br +0 -0
  99. package/dist/SurfaceChart3DScene-B3FK4Q2U.mjs.gz +0 -0
  100. package/dist/SurfaceChart3DScene-YJFWGG5L.js.br +0 -0
  101. package/dist/SurfaceChart3DScene-YJFWGG5L.js.gz +0 -0
  102. package/dist/chunk-25VSL2BB.js.br +0 -0
  103. package/dist/chunk-25VSL2BB.js.gz +0 -0
  104. package/dist/chunk-2UCJYJUS.mjs.br +0 -0
  105. package/dist/chunk-2UCJYJUS.mjs.gz +0 -0
  106. package/dist/chunk-BVK7K74O.js.br +0 -0
  107. package/dist/chunk-BVK7K74O.js.gz +0 -0
  108. package/dist/chunk-GRW7HM6X.js.br +0 -0
  109. package/dist/chunk-GRW7HM6X.js.gz +0 -0
  110. package/dist/chunk-HEAJOHLJ.mjs.br +0 -0
  111. package/dist/chunk-HEAJOHLJ.mjs.gz +0 -0
  112. package/dist/chunk-HQGLKAIY.mjs.br +0 -0
  113. package/dist/chunk-HQGLKAIY.mjs.gz +0 -0
  114. package/dist/chunk-IDK6XECR.mjs.br +0 -0
  115. package/dist/chunk-IDK6XECR.mjs.gz +0 -0
  116. package/dist/chunk-JEIMWRKF.js.br +0 -0
  117. package/dist/chunk-JEIMWRKF.js.gz +0 -0
  118. package/dist/chunk-JVE7BZ25.js.br +0 -0
  119. package/dist/chunk-JVE7BZ25.js.gz +0 -0
  120. package/dist/chunk-LYS44KMG.js.br +0 -0
  121. package/dist/chunk-LYS44KMG.js.gz +0 -0
  122. package/dist/chunk-N7EZIKF4.mjs.br +0 -0
  123. package/dist/chunk-N7EZIKF4.mjs.gz +0 -0
  124. package/dist/chunk-Z6HIZWIQ.mjs.br +0 -0
  125. package/dist/chunk-Z6HIZWIQ.mjs.gz +0 -0
  126. 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-HQGLKAIY.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, 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-HEAJOHLJ.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;
@@ -1882,20 +1877,13 @@ function useSlideNavigation(input) {
1882
1877
  });
1883
1878
  const scheduleAutoAdvanceForSlide = useCallback(
1884
1879
  (slideIndex) => {
1885
- if (useTimings === false) {
1886
- return;
1887
- }
1888
- const slide = slides[slideIndex];
1889
- const advanceAfterMs = slide?.transition?.advanceAfterMs;
1890
- if (typeof advanceAfterMs !== "number" || !Number.isFinite(advanceAfterMs) || advanceAfterMs < 0) {
1880
+ const delayMs = resolveAutoAdvanceDelayMs(slides[slideIndex], { useTimings });
1881
+ if (delayMs === void 0) {
1891
1882
  return;
1892
1883
  }
1893
- const timer = window.setTimeout(
1894
- () => {
1895
- movePresentationSlideRef.current(1);
1896
- },
1897
- Math.max(0, advanceAfterMs)
1898
- );
1884
+ const timer = window.setTimeout(() => {
1885
+ movePresentationSlideRef.current(1);
1886
+ }, delayMs);
1899
1887
  presentationTimersRef.current.push(timer);
1900
1888
  },
1901
1889
  [slides, presentationTimersRef, useTimings]
@@ -3599,6 +3587,7 @@ function useViewerUIState() {
3599
3587
  const [spellCheckEnabled, setSpellCheckEnabled] = useState(true);
3600
3588
  const [showGrid, setShowGrid] = useState(false);
3601
3589
  const [showRulers, setShowRulers] = useState(false);
3590
+ const [showGuides, setShowGuides] = useState(true);
3602
3591
  const [snapToGrid, setSnapToGrid] = useState(true);
3603
3592
  const [snapToShape, setSnapToShape] = useState(true);
3604
3593
  const [guides, setGuides] = useState(
@@ -3652,6 +3641,8 @@ function useViewerUIState() {
3652
3641
  setShowGrid,
3653
3642
  showRulers,
3654
3643
  setShowRulers,
3644
+ showGuides,
3645
+ setShowGuides,
3655
3646
  snapToGrid,
3656
3647
  setSnapToGrid,
3657
3648
  snapToShape,
@@ -4717,6 +4708,9 @@ function usePointerHandlers(input) {
4717
4708
  input
4718
4709
  ]);
4719
4710
  }
4711
+ function mouseDownStartsSelectionDrag(event) {
4712
+ return !event.shiftKey && !event.metaKey;
4713
+ }
4720
4714
  function useCanvasInteractions(input) {
4721
4715
  const {
4722
4716
  mode,
@@ -4829,6 +4823,9 @@ function useCanvasInteractions(input) {
4829
4823
  if (inlineEditingElementId && inlineEditingElementId !== elementId) {
4830
4824
  handleInlineEditCommit();
4831
4825
  }
4826
+ if (!mouseDownStartsSelectionDrag(e)) {
4827
+ return;
4828
+ }
4832
4829
  const wasSelected = selectedElementIdSet.has(elementId);
4833
4830
  if (!wasSelected) {
4834
4831
  ops.applySelection(elementId);
@@ -9276,140 +9273,77 @@ function useContentLifecycle(input) {
9276
9273
  });
9277
9274
  return { handlerRef, serializeSlides, autosaveStatus };
9278
9275
  }
9279
- var NUDGE_SMALL = 2;
9280
- var NUDGE_LARGE = 20;
9281
9276
  function useKeyboardShortcuts(input) {
9282
9277
  const inputRef = useRef(input);
9283
9278
  inputRef.current = input;
9284
9279
  const handleKeyDown = useCallback((e) => {
9285
- const {
9286
- mode,
9287
- canEdit,
9288
- inlineEditingElementId,
9289
- tableEditorState,
9290
- activeTool,
9291
- hasSelection,
9292
- onDelete,
9293
- onCopy,
9294
- onCut,
9295
- onPaste,
9296
- onDuplicate,
9297
- onUndo,
9298
- onRedo,
9299
- onSelectAll,
9300
- onEscape,
9301
- onNudge,
9302
- onPrevSlide,
9303
- onNextSlide
9304
- } = inputRef.current;
9305
- if (mode !== "edit" || !canEdit) {
9306
- return;
9307
- }
9308
- const target = e.target;
9309
- const isTextInput = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.isContentEditable;
9310
- if (e.key === "Escape") {
9311
- e.preventDefault();
9312
- onEscape();
9313
- return;
9314
- }
9315
- if (inlineEditingElementId || tableEditorState?.isEditing || activeTool !== "select") {
9316
- return;
9317
- }
9318
- if (isTextInput) {
9319
- return;
9320
- }
9321
- const isMod = e.metaKey || e.ctrlKey;
9322
- if ((e.key === "Delete" || e.key === "Backspace") && hasSelection) {
9323
- e.preventDefault();
9324
- onDelete();
9325
- return;
9326
- }
9327
- if (isMod) {
9328
- switch (e.key.toLowerCase()) {
9329
- case "z":
9330
- e.preventDefault();
9331
- if (e.shiftKey) {
9332
- onRedo();
9333
- } else {
9334
- onUndo();
9335
- }
9336
- return;
9337
- case "y":
9338
- e.preventDefault();
9339
- onRedo();
9340
- return;
9341
- case "c":
9342
- if (hasSelection) {
9343
- e.preventDefault();
9344
- onCopy();
9345
- }
9346
- return;
9347
- case "x":
9348
- if (hasSelection) {
9349
- e.preventDefault();
9350
- onCut();
9351
- }
9352
- return;
9353
- case "v":
9354
- e.preventDefault();
9355
- onPaste();
9356
- return;
9357
- case "d":
9358
- if (hasSelection) {
9359
- e.preventDefault();
9360
- onDuplicate();
9361
- }
9362
- return;
9363
- case "a":
9364
- e.preventDefault();
9365
- onSelectAll();
9366
- return;
9367
- }
9368
- }
9369
- if (hasSelection && (e.key === "ArrowUp" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowRight")) {
9370
- e.preventDefault();
9371
- const step = e.shiftKey ? NUDGE_LARGE : NUDGE_SMALL;
9372
- let dx = 0;
9373
- let dy = 0;
9374
- switch (e.key) {
9375
- case "ArrowUp":
9376
- dy = -step;
9377
- break;
9378
- case "ArrowDown":
9379
- dy = step;
9380
- break;
9381
- case "ArrowLeft":
9382
- dx = -step;
9383
- break;
9384
- case "ArrowRight":
9385
- dx = step;
9386
- break;
9387
- }
9388
- 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) {
9389
9290
  return;
9390
9291
  }
9391
- if (!hasSelection && (e.key === "ArrowLeft" || e.key === "ArrowRight")) {
9392
- e.preventDefault();
9393
- if (e.key === "ArrowLeft") {
9394
- onPrevSlide?.();
9395
- } else {
9396
- onNextSlide?.();
9397
- }
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;
9398
9339
  }
9399
9340
  }, []);
9400
9341
  useEffect(() => {
9401
- const container = input.containerRef.current;
9402
- if (container) {
9403
- container.addEventListener("keydown", handleKeyDown);
9404
- }
9405
9342
  window.addEventListener("keydown", handleKeyDown);
9406
9343
  return () => {
9407
- if (container) {
9408
- container.removeEventListener("keydown", handleKeyDown);
9409
- }
9410
9344
  window.removeEventListener("keydown", handleKeyDown);
9411
9345
  };
9412
- }, [input.containerRef, handleKeyDown]);
9346
+ }, [handleKeyDown]);
9413
9347
  }
9414
9348
 
9415
9349
  // src/viewer/hooks/useKeyboardShortcutWiring.ts
@@ -9440,8 +9374,13 @@ function useKeyboardShortcutWiring(input) {
9440
9374
  ops.applySelection(allIds[0], allIds);
9441
9375
  }
9442
9376
  },
9377
+ onGroup: manipulation.handleGroupElements,
9378
+ onUngroup: manipulation.handleUngroupElement,
9379
+ onToggleShortcuts: () => state.setIsShortcutHelpOpen((prev) => !prev),
9443
9380
  onEscape: () => {
9444
- if (state.inlineEditingElementId) {
9381
+ if (state.isShortcutHelpOpen) {
9382
+ state.setIsShortcutHelpOpen(false);
9383
+ } else if (state.inlineEditingElementId) {
9445
9384
  state.setInlineEditingElementId(null);
9446
9385
  state.setInlineEditingText("");
9447
9386
  } else if (state.contextMenuState) {
@@ -9638,7 +9577,7 @@ function useViewerIntegration(input) {
9638
9577
  return zoom.scale;
9639
9578
  },
9640
9579
  setZoom(level) {
9641
- zoom.setScale(Math.min(Math.max(level, MIN_ZOOM_SCALE), MAX_ZOOM_SCALE));
9580
+ zoom.setScale(clampZoomScale(level));
9642
9581
  },
9643
9582
  zoomIn() {
9644
9583
  zoom.handleZoomIn();
@@ -10342,29 +10281,11 @@ function buildCanvasProps(input) {
10342
10281
  } = input;
10343
10282
  const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
10344
10283
  const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
10345
- let slideTitle;
10346
- if (activeSlide) {
10347
- for (const el of activeSlide.elements) {
10348
- const phType = el.placeholderType;
10349
- if (phType === "title" || phType === "ctrTitle") {
10350
- const txt = el.text;
10351
- if (txt) {
10352
- slideTitle = txt;
10353
- break;
10354
- }
10355
- }
10356
- }
10357
- }
10358
- const hf = s.headerFooter;
10359
- const fieldContext = {
10360
- slideNumber: activeSlide?.slideNumber,
10361
- dateTimeText: hf.dateTimeText,
10362
- dateFormat: hf.dateFormat,
10363
- footerText: hf.footerText,
10364
- headerText: hf.headerText,
10365
- slideTitle,
10366
- customProperties: s.customProperties.map((p) => ({ name: p.name, value: p.value }))
10367
- };
10284
+ const fieldContext = buildFieldSubstitutionContext({
10285
+ headerFooter: s.headerFooter,
10286
+ customProperties: s.customProperties,
10287
+ slide: activeSlide
10288
+ });
10368
10289
  const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
10369
10290
  const handleActionClick = (_elementId, action) => {
10370
10291
  if (mode === "present") {
@@ -10408,7 +10329,9 @@ function buildCanvasProps(input) {
10408
10329
  showGrid: s.showGrid,
10409
10330
  gridSpacingPx,
10410
10331
  showRulers: s.showRulers,
10411
- 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 : [],
10412
10335
  presentationElementStates: mode === "present" ? presentation.presentationElementStates : void 0,
10413
10336
  presentationKeyframesCss: mode === "present" ? presentation.presentationKeyframesCss : void 0,
10414
10337
  onClick: canvasHandlers.handleElementClick,
@@ -10617,6 +10540,7 @@ function buildToolbarProps(input) {
10617
10540
  history
10618
10541
  });
10619
10542
  const scopedLayoutOptions = scopeLayoutOptionsToActiveSlide(s.layoutOptions, activeSlide);
10543
+ const selectionSize = selectedElement === null ? 0 : 1;
10620
10544
  return {
10621
10545
  fileName,
10622
10546
  mode,
@@ -10679,11 +10603,13 @@ function buildToolbarProps(input) {
10679
10603
  spellCheckEnabled: s.spellCheckEnabled,
10680
10604
  showGrid: s.showGrid,
10681
10605
  showRulers: s.showRulers,
10606
+ showGuides: s.showGuides,
10682
10607
  snapToGrid: s.snapToGrid,
10683
10608
  snapToShape: s.snapToShape,
10684
10609
  onSetSpellCheckEnabled: s.setSpellCheckEnabled,
10685
10610
  onSetShowGrid: s.setShowGrid,
10686
10611
  onSetShowRulers: s.setShowRulers,
10612
+ onSetShowGuides: s.setShowGuides,
10687
10613
  onSetSnapToGrid: s.setSnapToGrid,
10688
10614
  onSetSnapToShape: s.setSnapToShape,
10689
10615
  onAddGuide: dialogs.handleAddGuide,
@@ -10696,6 +10622,11 @@ function buildToolbarProps(input) {
10696
10622
  onFlip: manipulation.handleFlip,
10697
10623
  onMoveLayer: manipulation.handleMoveLayer,
10698
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),
10699
10630
  onDuplicate: manipulation.handleDuplicate,
10700
10631
  onDelete: manipulation.handleDelete,
10701
10632
  onExportPng: exportHandlers.handleExportPng,
Binary file
Binary file
@@ -1,4 +1,4 @@
1
- import { ThemePresets, PptxMarkdownConverter } from './chunk-HEAJOHLJ.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