@arbidocs/blocks 0.5.120 → 0.5.122
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.
- package/dist/ClippingMediaViewer-IEIBT74X.cjs +156 -0
- package/dist/ClippingMediaViewer-IEIBT74X.cjs.map +1 -0
- package/dist/ClippingPdfViewer-OGYLMVCE.cjs +79 -0
- package/dist/ClippingPdfViewer-OGYLMVCE.cjs.map +1 -0
- package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-XJOYVVAH.cjs} +9 -7
- package/dist/ConnectedCallDock-XJOYVVAH.cjs.map +1 -0
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-CUDYAPQK.cjs} +9 -7
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-CUDYAPQK.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs → ConnectedNativeDocxComparison-QKHCYD6W.cjs} +7 -7
- package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs.map → ConnectedNativeDocxComparison-QKHCYD6W.cjs.map} +1 -1
- package/dist/ConnectedPresentation-AU25OW25.cjs +321 -0
- package/dist/ConnectedPresentation-AU25OW25.cjs.map +1 -0
- package/dist/ConnectedSlidesTab-I75LKKN7.cjs +236 -0
- package/dist/ConnectedSlidesTab-I75LKKN7.cjs.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs → ConnectedStreamedWordArtifact-AG62232A.cjs} +7 -7
- package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map → ConnectedStreamedWordArtifact-AG62232A.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-BPIAJJED.cjs → DocumentReviewCard-M53XFLI2.cjs} +15 -14
- package/dist/DocumentReviewCard-M53XFLI2.cjs.map +1 -0
- package/dist/{FilesViewerDialog-67WK3TZC.cjs → FilesViewerDialog-4352KIOG.cjs} +30 -22
- package/dist/FilesViewerDialog-4352KIOG.cjs.map +1 -0
- package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
- package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
- package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-3XYAV4BV.cjs} +9 -8
- package/dist/WorkspaceTableView-3XYAV4BV.cjs.map +1 -0
- package/dist/agents/index.cjs +186 -186
- package/dist/{ai-IM4A23YT.cjs → ai-IEIR7SC2.cjs} +17 -15
- package/dist/ai-IEIR7SC2.cjs.map +1 -0
- package/dist/calls/connected/CallControls.d.ts +2 -0
- package/dist/calls/connected/CallControls.js +71 -9
- package/dist/calls/connected/CallControls.js.map +2 -2
- package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
- package/dist/calls/connected/ShareDocumentDialog.js +77 -0
- package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
- package/dist/calls/index.cjs +2 -2
- package/dist/chat/index.cjs +8 -7
- package/dist/{chunk-557MJ4IH.cjs → chunk-2F57IO7S.cjs} +9 -146
- package/dist/chunk-2F57IO7S.cjs.map +1 -0
- package/dist/chunk-2RLA6QO2.cjs +174 -0
- package/dist/chunk-2RLA6QO2.cjs.map +1 -0
- package/dist/chunk-4TTX6ZNS.cjs +1374 -0
- package/dist/chunk-4TTX6ZNS.cjs.map +1 -0
- package/dist/chunk-5GCCUXMT.cjs +63 -0
- package/dist/chunk-5GCCUXMT.cjs.map +1 -0
- package/dist/{chunk-BUVIBHFU.cjs → chunk-5QERK4PK.cjs} +38 -38
- package/dist/chunk-5QERK4PK.cjs.map +1 -0
- package/dist/chunk-6OK7ESTL.cjs +134 -0
- package/dist/chunk-6OK7ESTL.cjs.map +1 -0
- package/dist/{chunk-ECLUFKYR.cjs → chunk-7557LDAN.cjs} +4 -4
- package/dist/{chunk-ECLUFKYR.cjs.map → chunk-7557LDAN.cjs.map} +1 -1
- package/dist/{chunk-KTQOGT2L.cjs → chunk-7L4X6QN2.cjs} +7 -7
- package/dist/{chunk-KTQOGT2L.cjs.map → chunk-7L4X6QN2.cjs.map} +1 -1
- package/dist/{chunk-BP3IJ34D.cjs → chunk-7NLO7ASW.cjs} +4 -4
- package/dist/{chunk-BP3IJ34D.cjs.map → chunk-7NLO7ASW.cjs.map} +1 -1
- package/dist/{chunk-3GWWOYGS.cjs → chunk-7PN3YENO.cjs} +4 -4
- package/dist/{chunk-3GWWOYGS.cjs.map → chunk-7PN3YENO.cjs.map} +1 -1
- package/dist/{chunk-DFBDQKGE.cjs → chunk-ADDQKZ5I.cjs} +4 -4
- package/dist/{chunk-DFBDQKGE.cjs.map → chunk-ADDQKZ5I.cjs.map} +1 -1
- package/dist/chunk-AFQTQC7A.cjs +35 -0
- package/dist/chunk-AFQTQC7A.cjs.map +1 -0
- package/dist/{chunk-NLSWDP42.cjs → chunk-ALK3PUUB.cjs} +21 -11
- package/dist/chunk-ALK3PUUB.cjs.map +1 -0
- package/dist/{chunk-775S43W7.cjs → chunk-CQQQIZU4.cjs} +8 -8
- package/dist/{chunk-775S43W7.cjs.map → chunk-CQQQIZU4.cjs.map} +1 -1
- package/dist/{chunk-TDO5UWXF.cjs → chunk-E3L5DB5F.cjs} +5 -5
- package/dist/{chunk-TDO5UWXF.cjs.map → chunk-E3L5DB5F.cjs.map} +1 -1
- package/dist/chunk-GFUOCGY6.cjs +32 -0
- package/dist/chunk-GFUOCGY6.cjs.map +1 -0
- package/dist/chunk-HYUKPHCT.cjs +66 -0
- package/dist/chunk-HYUKPHCT.cjs.map +1 -0
- package/dist/{chunk-QQWHG3KF.cjs → chunk-JJZOL5MG.cjs} +4 -4
- package/dist/{chunk-QQWHG3KF.cjs.map → chunk-JJZOL5MG.cjs.map} +1 -1
- package/dist/chunk-K4763GD5.cjs +301 -0
- package/dist/chunk-K4763GD5.cjs.map +1 -0
- package/dist/{chunk-B3LZITVF.cjs → chunk-KA3F6TIH.cjs} +2 -442
- package/dist/chunk-KA3F6TIH.cjs.map +1 -0
- package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
- package/dist/chunk-KNGZZC4O.cjs.map +1 -0
- package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
- package/dist/chunk-LHWOKOMP.cjs.map +1 -0
- package/dist/{chunk-HA66DHW6.cjs → chunk-MLA2BJ2Y.cjs} +28 -28
- package/dist/chunk-MLA2BJ2Y.cjs.map +1 -0
- package/dist/{chunk-CPR6EHG7.cjs → chunk-NG2EE7HR.cjs} +134 -10
- package/dist/chunk-NG2EE7HR.cjs.map +1 -0
- package/dist/{chunk-CKCG4NDB.cjs → chunk-OHHKBURG.cjs} +29 -29
- package/dist/chunk-OHHKBURG.cjs.map +1 -0
- package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
- package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
- package/dist/{chunk-YYSBWMDJ.cjs → chunk-QG2U2JGX.cjs} +4 -4
- package/dist/{chunk-YYSBWMDJ.cjs.map → chunk-QG2U2JGX.cjs.map} +1 -1
- package/dist/{chunk-5IZFSAEZ.cjs → chunk-SDRYSLOX.cjs} +4 -4
- package/dist/{chunk-5IZFSAEZ.cjs.map → chunk-SDRYSLOX.cjs.map} +1 -1
- package/dist/{chunk-NJCK6V6U.cjs → chunk-T73BHNQX.cjs} +2 -58
- package/dist/chunk-T73BHNQX.cjs.map +1 -0
- package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
- package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
- package/dist/{chunk-6UTKM5AB.cjs → chunk-UFT22LAB.cjs} +75 -75
- package/dist/chunk-UFT22LAB.cjs.map +1 -0
- package/dist/chunk-USNTRL22.cjs +4790 -0
- package/dist/chunk-USNTRL22.cjs.map +1 -0
- package/dist/{chunk-X36UR4A7.cjs → chunk-UTJ223TI.cjs} +413 -90
- package/dist/chunk-UTJ223TI.cjs.map +1 -0
- package/dist/{chunk-VZCPMXWC.cjs → chunk-V6MW7B4B.cjs} +4 -4
- package/dist/{chunk-VZCPMXWC.cjs.map → chunk-V6MW7B4B.cjs.map} +1 -1
- package/dist/{chunk-T23UTIRI.cjs → chunk-VWBYE3XY.cjs} +5 -5
- package/dist/{chunk-T23UTIRI.cjs.map → chunk-VWBYE3XY.cjs.map} +1 -1
- package/dist/chunk-WFMWKPGY.cjs +102 -0
- package/dist/chunk-WFMWKPGY.cjs.map +1 -0
- package/dist/chunk-WOOOMTTA.cjs +19 -0
- package/dist/chunk-WOOOMTTA.cjs.map +1 -0
- package/dist/{chunk-W6INT5GS.cjs → chunk-WRLGLZIA.cjs} +8 -8
- package/dist/{chunk-W6INT5GS.cjs.map → chunk-WRLGLZIA.cjs.map} +1 -1
- package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
- package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
- package/dist/chunk-XF355M7O.cjs +154 -0
- package/dist/chunk-XF355M7O.cjs.map +1 -0
- package/dist/{chunk-Q6CLWOP2.cjs → chunk-XGM4VVNV.cjs} +34 -34
- package/dist/{chunk-Q6CLWOP2.cjs.map → chunk-XGM4VVNV.cjs.map} +1 -1
- package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
- package/dist/chunk-XJEXFEWG.cjs.map +1 -0
- package/dist/chunk-XK4TVJKD.cjs +73 -0
- package/dist/chunk-XK4TVJKD.cjs.map +1 -0
- package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
- package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
- package/dist/collaboration/index.cjs +70 -70
- package/dist/components/ZoomSlider.d.ts +25 -0
- package/dist/components/ZoomSlider.js +59 -0
- package/dist/components/ZoomSlider.js.map +7 -0
- package/dist/connect/docx.cjs +10 -10
- package/dist/connect/index.cjs +1066 -1147
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/viewer.cjs +19 -12
- package/dist/connection/ai.d.ts +1 -1
- package/dist/connection/conversation/ConnectedMessage.js +1 -1
- package/dist/connection/conversation/ConnectedMessage.js.map +2 -2
- package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
- package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
- package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
- package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
- package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
- package/dist/connection/files/explorer/FileTiles.js +1 -1
- package/dist/connection/files/explorer/FileTiles.js.map +2 -2
- package/dist/connection/files/fields/documentField.js +1 -1
- package/dist/connection/files/fields/documentField.js.map +2 -2
- package/dist/connection/files/grid/documentColumns.js +1 -1
- package/dist/connection/files/grid/documentColumns.js.map +2 -2
- package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
- package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
- package/dist/connection/mail/useMailboxDefaults.js +1 -1
- package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
- package/dist/connection/panels/useSessionPanelMode.js +3 -2
- package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
- package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
- package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
- package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
- package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
- package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
- package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
- package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
- package/dist/connection/presentation/ConnectedPresentation.js +100 -0
- package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
- package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
- package/dist/connection/presentation/ConnectedSlidesTab.js +222 -0
- package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
- package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
- package/dist/connection/presentation/CropClipDialog.js +86 -0
- package/dist/connection/presentation/CropClipDialog.js.map +7 -0
- package/dist/connection/presentation/GenerateTile.d.ts +4 -0
- package/dist/connection/presentation/GenerateTile.js +24 -0
- package/dist/connection/presentation/GenerateTile.js.map +7 -0
- package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
- package/dist/connection/presentation/LabelColumnMenu.js +38 -0
- package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
- package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
- package/dist/connection/presentation/PresentationDialogs.js +295 -0
- package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
- package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
- package/dist/connection/presentation/PresentationFileCard.js +35 -0
- package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
- package/dist/connection/presentation/PresentationPill.d.ts +8 -0
- package/dist/connection/presentation/PresentationPill.js +39 -0
- package/dist/connection/presentation/PresentationPill.js.map +7 -0
- package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
- package/dist/connection/presentation/PresentationSlot.js +35 -0
- package/dist/connection/presentation/PresentationSlot.js.map +7 -0
- package/dist/connection/presentation/requests.d.ts +21 -0
- package/dist/connection/presentation/requests.js +27 -0
- package/dist/connection/presentation/requests.js.map +7 -0
- package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
- package/dist/connection/presentation/useImageGeneration.js +66 -0
- package/dist/connection/presentation/useImageGeneration.js.map +7 -0
- package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
- package/dist/connection/presentation/useLabelColumns.js +33 -0
- package/dist/connection/presentation/useLabelColumns.js.map +7 -0
- package/dist/connection/presentation/usePresentationController.d.ts +15 -0
- package/dist/connection/presentation/usePresentationController.js +118 -0
- package/dist/connection/presentation/usePresentationController.js.map +7 -0
- package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
- package/dist/connection/presentation/usePresentationFiles.js +307 -0
- package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
- package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
- package/dist/connection/presentation/useViewerClipping.js +18 -0
- package/dist/connection/presentation/useViewerClipping.js.map +7 -0
- package/dist/connection/shell/ConnectedAppShell.js +5 -1
- package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
- package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
- package/dist/connection/viewer/CleanViewControl.js +76 -0
- package/dist/connection/viewer/CleanViewControl.js.map +7 -0
- package/dist/connection/viewer/ConnectedDocumentViewer.js +28 -29
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
- package/dist/connection/viewer/ViewerCropModal.js +22 -0
- package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
- package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
- package/dist/connection/viewer/ViewerPdfPane.js +41 -1
- package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
- package/dist/connection/viewer/documentPlace.d.ts +5 -4
- package/dist/connection/viewer/documentPlace.js +2 -2
- package/dist/connection/viewer/documentPlace.js.map +2 -2
- package/dist/connection/viewer/drafts.js +6 -4
- package/dist/connection/viewer/drafts.js.map +2 -2
- package/dist/connection/viewer/pdf/PdfClipOutlines.d.ts +11 -0
- package/dist/connection/viewer/pdf/PdfClipOutlines.js +42 -0
- package/dist/connection/viewer/pdf/PdfClipOutlines.js.map +7 -0
- package/dist/connection/viewer/pdf/clipOutlines.d.ts +17 -0
- package/dist/connection/viewer/pdf/clipOutlines.js +24 -0
- package/dist/connection/viewer/pdf/clipOutlines.js.map +7 -0
- package/dist/connection/viewer/pdf/passageHighlights.d.ts +2 -0
- package/dist/connection/viewer/pdf/passageHighlights.js +12 -1
- package/dist/connection/viewer/pdf/passageHighlights.js.map +2 -2
- package/dist/connection/viewer/pdf/usePdfClipOutlines.d.ts +7 -0
- package/dist/connection/viewer/pdf/usePdfClipOutlines.js +36 -0
- package/dist/connection/viewer/pdf/usePdfClipOutlines.js.map +7 -0
- package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +11 -2
- package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +2 -2
- package/dist/connection/viewer/shareDocument.d.ts +11 -0
- package/dist/connection/viewer/shareDocument.js +11 -0
- package/dist/connection/viewer/shareDocument.js.map +7 -0
- package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
- package/dist/connection/viewer/slidesTabChunk.js +9 -0
- package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
- package/dist/connection/viewer/useCleanView.d.ts +14 -0
- package/dist/connection/viewer/useCleanView.js +29 -0
- package/dist/connection/viewer/useCleanView.js.map +7 -0
- package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
- package/dist/connection/viewer/useViewedDocument.js +9 -1
- package/dist/connection/viewer/useViewedDocument.js.map +2 -2
- package/dist/connection/viewer/useViewerTabs.js +18 -4
- package/dist/connection/viewer/useViewerTabs.js.map +2 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
- package/dist/databases/index.cjs +49 -49
- package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
- package/dist/document-tools/DocumentToolButtons.js +22 -1
- package/dist/document-tools/DocumentToolButtons.js.map +2 -2
- package/dist/document-tools/index.cjs +16 -12
- package/dist/document-tools/index.d.ts +1 -1
- package/dist/document-tools/index.js +2 -0
- package/dist/document-tools/index.js.map +2 -2
- package/dist/embed/index.cjs +17 -15
- package/dist/files/GridViewImpl.js +1 -1
- package/dist/files/GridViewImpl.js.map +2 -2
- package/dist/files/ViewerChrome.d.ts +5 -1
- package/dist/files/ViewerChrome.js +16 -6
- package/dist/files/ViewerChrome.js.map +2 -2
- package/dist/files/index.cjs +224 -224
- package/dist/files/navigator/DocumentSearchList.js +1 -1
- package/dist/files/navigator/DocumentSearchList.js.map +2 -2
- package/dist/index.cjs +359 -356
- package/dist/index.cjs.map +1 -1
- package/dist/presentation/BoxActionBar.d.ts +11 -0
- package/dist/presentation/BoxActionBar.js +182 -0
- package/dist/presentation/BoxActionBar.js.map +7 -0
- package/dist/presentation/ClipActionBar.d.ts +26 -0
- package/dist/presentation/ClipActionBar.js +103 -0
- package/dist/presentation/ClipActionBar.js.map +7 -0
- package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
- package/dist/presentation/ClipCaptureOverlay.js +69 -0
- package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
- package/dist/presentation/ClipImage.d.ts +21 -0
- package/dist/presentation/ClipImage.js +119 -0
- package/dist/presentation/ClipImage.js.map +7 -0
- package/dist/presentation/ClipTray.d.ts +11 -0
- package/dist/presentation/ClipTray.js +152 -0
- package/dist/presentation/ClipTray.js.map +7 -0
- package/dist/presentation/ClipViewControls.d.ts +11 -0
- package/dist/presentation/ClipViewControls.js +142 -0
- package/dist/presentation/ClipViewControls.js.map +7 -0
- package/dist/presentation/DesignMenu.d.ts +8 -0
- package/dist/presentation/DesignMenu.js +199 -0
- package/dist/presentation/DesignMenu.js.map +7 -0
- package/dist/presentation/LayoutMenu.d.ts +17 -0
- package/dist/presentation/LayoutMenu.js +122 -0
- package/dist/presentation/LayoutMenu.js.map +7 -0
- package/dist/presentation/MediaClip.d.ts +15 -0
- package/dist/presentation/MediaClip.js +67 -0
- package/dist/presentation/MediaClip.js.map +7 -0
- package/dist/presentation/Notice.d.ts +6 -0
- package/dist/presentation/Notice.js +43 -0
- package/dist/presentation/Notice.js.map +7 -0
- package/dist/presentation/PresentControls.d.ts +11 -0
- package/dist/presentation/PresentControls.js +117 -0
- package/dist/presentation/PresentControls.js.map +7 -0
- package/dist/presentation/PresentationStage.d.ts +32 -0
- package/dist/presentation/PresentationStage.js +232 -0
- package/dist/presentation/PresentationStage.js.map +7 -0
- package/dist/presentation/PresenterView.d.ts +16 -0
- package/dist/presentation/PresenterView.js +100 -0
- package/dist/presentation/PresenterView.js.map +7 -0
- package/dist/presentation/SlideDecor.d.ts +25 -0
- package/dist/presentation/SlideDecor.js +189 -0
- package/dist/presentation/SlideDecor.js.map +7 -0
- package/dist/presentation/SlidesEditor.d.ts +25 -0
- package/dist/presentation/SlidesEditor.js +375 -0
- package/dist/presentation/SlidesEditor.js.map +7 -0
- package/dist/presentation/StageBox.d.ts +30 -0
- package/dist/presentation/StageBox.js +281 -0
- package/dist/presentation/StageBox.js.map +7 -0
- package/dist/presentation/StageItem.d.ts +37 -0
- package/dist/presentation/StageItem.js +211 -0
- package/dist/presentation/StageItem.js.map +7 -0
- package/dist/presentation/box-style.d.ts +6 -0
- package/dist/presentation/box-style.js +19 -0
- package/dist/presentation/box-style.js.map +7 -0
- package/dist/presentation/boxes.d.ts +105 -0
- package/dist/presentation/boxes.js +103 -0
- package/dist/presentation/boxes.js.map +7 -0
- package/dist/presentation/draw-boxes.d.ts +8 -0
- package/dist/presentation/draw-boxes.js +130 -0
- package/dist/presentation/draw-boxes.js.map +7 -0
- package/dist/presentation/export-boxes.d.ts +10 -0
- package/dist/presentation/export-boxes.js +74 -0
- package/dist/presentation/export-boxes.js.map +7 -0
- package/dist/presentation/export-pptx.d.ts +16 -0
- package/dist/presentation/export-pptx.js +194 -0
- package/dist/presentation/export-pptx.js.map +7 -0
- package/dist/presentation/import-pptx.d.ts +35 -0
- package/dist/presentation/import-pptx.js +659 -0
- package/dist/presentation/import-pptx.js.map +7 -0
- package/dist/presentation/merge-outside-edits.d.ts +12 -0
- package/dist/presentation/merge-outside-edits.js +35 -0
- package/dist/presentation/merge-outside-edits.js.map +7 -0
- package/dist/presentation/model.d.ts +201 -0
- package/dist/presentation/model.js +271 -0
- package/dist/presentation/model.js.map +7 -0
- package/dist/presentation/panel-id.d.ts +44 -0
- package/dist/presentation/panel-id.js +29 -0
- package/dist/presentation/panel-id.js.map +7 -0
- package/dist/presentation/persistence.d.ts +121 -0
- package/dist/presentation/persistence.js +141 -0
- package/dist/presentation/persistence.js.map +7 -0
- package/dist/presentation/pptx-data.d.ts +22 -0
- package/dist/presentation/pptx-data.js +83 -0
- package/dist/presentation/pptx-data.js.map +7 -0
- package/dist/presentation/pptx-xml.d.ts +90 -0
- package/dist/presentation/pptx-xml.js +333 -0
- package/dist/presentation/pptx-xml.js.map +7 -0
- package/dist/presentation/render-slides.d.ts +58 -0
- package/dist/presentation/render-slides.js +309 -0
- package/dist/presentation/render-slides.js.map +7 -0
- package/dist/presentation/saved-boxes.d.ts +11 -0
- package/dist/presentation/saved-boxes.js +80 -0
- package/dist/presentation/saved-boxes.js.map +7 -0
- package/dist/presentation/slide-layout.d.ts +58 -0
- package/dist/presentation/slide-layout.js +133 -0
- package/dist/presentation/slide-layout.js.map +7 -0
- package/dist/presentation/stage-videos.d.ts +5 -0
- package/dist/presentation/stage-videos.js +19 -0
- package/dist/presentation/stage-videos.js.map +7 -0
- package/dist/presentation/store.d.ts +203 -0
- package/dist/presentation/store.js +429 -0
- package/dist/presentation/store.js.map +7 -0
- package/dist/presentation/theme.d.ts +102 -0
- package/dist/presentation/theme.js +276 -0
- package/dist/presentation/theme.js.map +7 -0
- package/dist/presentation/useClipDrag.d.ts +26 -0
- package/dist/presentation/useClipDrag.js +65 -0
- package/dist/presentation/useClipDrag.js.map +7 -0
- package/dist/presentation/useObjectUrl.d.ts +6 -0
- package/dist/presentation/useObjectUrl.js +15 -0
- package/dist/presentation/useObjectUrl.js.map +7 -0
- package/dist/presentation/usePresenterKeys.d.ts +13 -0
- package/dist/presentation/usePresenterKeys.js +62 -0
- package/dist/presentation/usePresenterKeys.js.map +7 -0
- package/dist/settings/index.cjs +149 -148
- package/dist/shell/PanelPortal.js +13 -3
- package/dist/shell/PanelPortal.js.map +2 -2
- package/dist/shell/index.cjs +49 -46
- package/dist/shell/panel-windows.d.ts +2 -0
- package/dist/shell/panel-windows.js +8 -2
- package/dist/shell/panel-windows.js.map +2 -2
- package/dist/studio/index.cjs +8 -6
- package/dist/studio/index.cjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +26 -25
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +6 -5
- package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
- package/dist/DocumentReviewCard-BPIAJJED.cjs.map +0 -1
- package/dist/FilesViewerDialog-67WK3TZC.cjs.map +0 -1
- package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
- package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
- package/dist/ai-IM4A23YT.cjs.map +0 -1
- package/dist/chunk-557MJ4IH.cjs.map +0 -1
- package/dist/chunk-6UTKM5AB.cjs.map +0 -1
- package/dist/chunk-6WMMZLEV.cjs.map +0 -1
- package/dist/chunk-B3LZITVF.cjs.map +0 -1
- package/dist/chunk-BUVIBHFU.cjs.map +0 -1
- package/dist/chunk-CKCG4NDB.cjs.map +0 -1
- package/dist/chunk-CPR6EHG7.cjs.map +0 -1
- package/dist/chunk-HA66DHW6.cjs.map +0 -1
- package/dist/chunk-NJCK6V6U.cjs.map +0 -1
- package/dist/chunk-NLSWDP42.cjs.map +0 -1
- package/dist/chunk-PGJYD67F.cjs.map +0 -1
- package/dist/chunk-X36UR4A7.cjs.map +0 -1
- package/dist/chunk-YYPZOEED.cjs.map +0 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { memo, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
|
+
import { closePdfRegionImage, renderPdfRegion } from "@arbidocs/react/viewers";
|
|
5
|
+
import { cn } from "@arbidocs/react/ui";
|
|
6
|
+
import { MediaClip } from "./MediaClip.js";
|
|
7
|
+
const WIDTH_STEP = 160;
|
|
8
|
+
const SETTLE_MS = 150;
|
|
9
|
+
const ClipImage = memo(function ClipImage2({
|
|
10
|
+
clip,
|
|
11
|
+
className,
|
|
12
|
+
live = false
|
|
13
|
+
}) {
|
|
14
|
+
return clip.kind === "pdf" ? /* @__PURE__ */ jsx(PdfClip, { clip, className }) : /* @__PURE__ */ jsx(MediaClip, { clip, className, live });
|
|
15
|
+
});
|
|
16
|
+
const sameRect = (a, b) => a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
|
|
17
|
+
function PdfClip({ clip, className }) {
|
|
18
|
+
const canvasRef = useRef(null);
|
|
19
|
+
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
20
|
+
const [rendered, setRendered] = useState(null);
|
|
21
|
+
const [failed, setFailed] = useState(false);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const canvas = canvasRef.current;
|
|
24
|
+
const view = canvas?.ownerDocument.defaultView;
|
|
25
|
+
if (!canvas || !view) return;
|
|
26
|
+
const measure = () => {
|
|
27
|
+
const box = canvas.getBoundingClientRect();
|
|
28
|
+
const dpr = view.devicePixelRatio || 1;
|
|
29
|
+
const width = Math.max(1, Math.round(box.width * dpr));
|
|
30
|
+
const height = Math.max(1, Math.round(box.height * dpr));
|
|
31
|
+
setSize((s) => s.width === width && s.height === height ? s : { width, height });
|
|
32
|
+
};
|
|
33
|
+
measure();
|
|
34
|
+
const Observer = view.ResizeObserver ?? ResizeObserver;
|
|
35
|
+
const observer = new Observer(measure);
|
|
36
|
+
observer.observe(canvas);
|
|
37
|
+
return () => observer.disconnect();
|
|
38
|
+
}, []);
|
|
39
|
+
useLayoutEffect(() => {
|
|
40
|
+
const canvas = canvasRef.current;
|
|
41
|
+
const context = canvas?.getContext("2d");
|
|
42
|
+
if (!canvas || !context || !size.width) return;
|
|
43
|
+
if (canvas.width !== size.width) canvas.width = size.width;
|
|
44
|
+
if (canvas.height !== size.height) canvas.height = size.height;
|
|
45
|
+
context.fillStyle = "#fff";
|
|
46
|
+
context.fillRect(0, 0, size.width, size.height);
|
|
47
|
+
if (!rendered) return;
|
|
48
|
+
const { rect } = clip;
|
|
49
|
+
const sx = size.width / rect.w;
|
|
50
|
+
const sy = size.height / rect.h;
|
|
51
|
+
try {
|
|
52
|
+
context.drawImage(
|
|
53
|
+
rendered.image,
|
|
54
|
+
(rendered.rect.x - rect.x) * sx,
|
|
55
|
+
(rendered.rect.y - rect.y) * sy,
|
|
56
|
+
rendered.rect.w * sx,
|
|
57
|
+
rendered.rect.h * sy
|
|
58
|
+
);
|
|
59
|
+
} catch {
|
|
60
|
+
setRendered(null);
|
|
61
|
+
}
|
|
62
|
+
}, [size, rendered, clip]);
|
|
63
|
+
const wanted = Math.ceil(size.width / WIDTH_STEP) * WIDTH_STEP;
|
|
64
|
+
const stale = wanted > 0 && (!rendered || !sameRect(rendered.rect, clip.rect) || wanted > rendered.width || wanted < rendered.width / 2);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!stale) return;
|
|
67
|
+
const controller = new AbortController();
|
|
68
|
+
const rect = clip.rect;
|
|
69
|
+
const timer = setTimeout(() => {
|
|
70
|
+
renderPdfRegion({
|
|
71
|
+
file: clip.source,
|
|
72
|
+
page: clip.page,
|
|
73
|
+
rect,
|
|
74
|
+
masks: clip.masks,
|
|
75
|
+
width: wanted,
|
|
76
|
+
signal: controller.signal
|
|
77
|
+
}).then((image) => {
|
|
78
|
+
if (controller.signal.aborted) return closePdfRegionImage(image);
|
|
79
|
+
setFailed(false);
|
|
80
|
+
setRendered({ image, rect, width: wanted });
|
|
81
|
+
}).catch(() => !controller.signal.aborted && setFailed(true));
|
|
82
|
+
}, SETTLE_MS);
|
|
83
|
+
return () => {
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
controller.abort();
|
|
86
|
+
};
|
|
87
|
+
}, [stale, wanted, clip.source, clip.page, clip.rect, clip.masks]);
|
|
88
|
+
const previous = useRef(null);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (previous.current && previous.current !== rendered) {
|
|
91
|
+
closePdfRegionImage(previous.current.image);
|
|
92
|
+
}
|
|
93
|
+
previous.current = rendered;
|
|
94
|
+
}, [rendered]);
|
|
95
|
+
return /* @__PURE__ */ jsxs(
|
|
96
|
+
"div",
|
|
97
|
+
{
|
|
98
|
+
className: cn("relative h-full w-full overflow-hidden bg-white", className),
|
|
99
|
+
"data-testid": `clip-image-${clip.id}`,
|
|
100
|
+
children: [
|
|
101
|
+
/* @__PURE__ */ jsx(
|
|
102
|
+
"canvas",
|
|
103
|
+
{
|
|
104
|
+
ref: canvasRef,
|
|
105
|
+
className: "pointer-events-none block h-full w-full",
|
|
106
|
+
role: "img",
|
|
107
|
+
"aria-label": clip.caption,
|
|
108
|
+
"aria-busy": !rendered
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
failed && !rendered && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center p-2 text-center text-xs text-neutral-500", children: "Couldn't draw this clip" })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
ClipImage
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=ClipImage.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/ClipImage.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * A clip as shown on a slide or in the tray.\n *\n * A PDF clip is drawn into a canvas the size of its box in device pixels (measured in whichever\n * window it is in), from a bitmap of its region rendered for that size: as sharp as the screen\n * allows. The canvas remembers what area its bitmap covers, so when the clip is scrolled or\n * resized it is redrawn at once from the bitmap it has (shifted or scaled: cheap), and the sharp\n * rendering follows once the change settles. An older render still running is cancelled; renders\n * across clips are queued a few at a time (`renderPdfRegion`), so the page stays smooth.\n *\n * An image or video clip is its own file, cropped (`MediaClip`).\n */\n\nimport { memo, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { closePdfRegionImage, renderPdfRegion, type PdfRegionImage } from '@arbidocs/react/viewers'\nimport { cn } from '@arbidocs/react/ui'\nimport { MediaClip } from './MediaClip'\nimport type { Clip, Rect } from './model'\n\n/** Rendered widths are rounded up to this step, so small size changes reuse the rendering. */\nconst WIDTH_STEP = 160\n/** A new rendering is asked for once the clip has stopped changing for this long. */\nconst SETTLE_MS = 150\n\nexport interface ClipImageProps {\n clip: Clip\n className?: string\n /** On the presented stage: a video clip plays with its sound (the editor's copy is muted). */\n live?: boolean\n}\n\n/** An image or video clip is its own file, cropped; a PDF clip is drawn for its size. */\nexport const ClipImage = memo(function ClipImage({\n clip,\n className,\n live = false,\n}: ClipImageProps) {\n return clip.kind === 'pdf' ? (\n <PdfClip clip={clip} className={className} />\n ) : (\n <MediaClip clip={clip} className={className} live={live} />\n )\n})\n\ninterface Rendered {\n image: PdfRegionImage\n /** The page area the image shows. */\n rect: Rect\n /** Its width in device pixels. */\n width: number\n}\n\nconst sameRect = (a: Rect, b: Rect) => a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h\n\nfunction PdfClip({ clip, className }: Omit<ClipImageProps, 'live'>) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n // The canvas's size in device pixels.\n const [size, setSize] = useState({ width: 0, height: 0 })\n const [rendered, setRendered] = useState<Rendered | null>(null)\n const [failed, setFailed] = useState(false)\n\n // Size the canvas to its box in its own window's device pixels.\n useEffect(() => {\n const canvas = canvasRef.current\n const view = canvas?.ownerDocument.defaultView\n if (!canvas || !view) return\n const measure = () => {\n const box = canvas.getBoundingClientRect()\n const dpr = view.devicePixelRatio || 1\n const width = Math.max(1, Math.round(box.width * dpr))\n const height = Math.max(1, Math.round(box.height * dpr))\n setSize((s) => (s.width === width && s.height === height ? s : { width, height }))\n }\n measure()\n const Observer = (view as typeof window).ResizeObserver ?? ResizeObserver\n const observer = new Observer(measure)\n observer.observe(canvas)\n return () => observer.disconnect()\n }, [])\n\n // Draw what there is now: the last rendering placed where its area falls in the clip's area.\n useLayoutEffect(() => {\n const canvas = canvasRef.current\n const context = canvas?.getContext('2d')\n if (!canvas || !context || !size.width) return\n if (canvas.width !== size.width) canvas.width = size.width\n if (canvas.height !== size.height) canvas.height = size.height\n context.fillStyle = '#fff'\n context.fillRect(0, 0, size.width, size.height)\n if (!rendered) return\n const { rect } = clip\n const sx = size.width / rect.w\n const sy = size.height / rect.h\n try {\n context.drawImage(\n rendered.image,\n (rendered.rect.x - rect.x) * sx,\n (rendered.rect.y - rect.y) * sy,\n rendered.rect.w * sx,\n rendered.rect.h * sy\n )\n } catch {\n // A rendering already freed: draw it again rather than fail.\n setRendered(null)\n }\n }, [size, rendered, clip])\n\n // Render the region again once the clip has settled, if what is drawn is not sharp or not it.\n const wanted = Math.ceil(size.width / WIDTH_STEP) * WIDTH_STEP\n const stale =\n wanted > 0 &&\n (!rendered ||\n !sameRect(rendered.rect, clip.rect) ||\n wanted > rendered.width ||\n wanted < rendered.width / 2)\n useEffect(() => {\n if (!stale) return\n const controller = new AbortController()\n const rect = clip.rect\n const timer = setTimeout(() => {\n renderPdfRegion({\n file: clip.source,\n page: clip.page,\n rect,\n masks: clip.masks,\n width: wanted,\n signal: controller.signal,\n })\n .then((image) => {\n if (controller.signal.aborted) return closePdfRegionImage(image)\n setFailed(false)\n setRendered({ image, rect, width: wanted })\n })\n .catch(() => !controller.signal.aborted && setFailed(true))\n }, SETTLE_MS)\n return () => {\n clearTimeout(timer)\n controller.abort()\n }\n }, [stale, wanted, clip.source, clip.page, clip.rect, clip.masks])\n\n // A rendering's memory is freed once the next has replaced it on screen. Never in a cleanup: a\n // remount (React's StrictMode replays mount effects) would free the one still in use. One left\n // when the clip goes is reclaimed by the browser with it.\n const previous = useRef<Rendered | null>(null)\n useEffect(() => {\n if (previous.current && previous.current !== rendered) {\n closePdfRegionImage(previous.current.image)\n }\n previous.current = rendered\n }, [rendered])\n\n return (\n <div\n className={cn('relative h-full w-full overflow-hidden bg-white', className)}\n data-testid={`clip-image-${clip.id}`}\n >\n <canvas\n ref={canvasRef}\n className=\"pointer-events-none block h-full w-full\"\n role=\"img\"\n aria-label={clip.caption}\n aria-busy={!rendered}\n />\n {failed && !rendered && (\n <div className=\"absolute inset-0 flex items-center justify-center p-2 text-center text-xs text-neutral-500\">\n {\"Couldn't draw this clip\"}\n </div>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ClipImage"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The clips taken so far, as a strip of tiles along the bottom (the files explorer's tile look).
|
|
3
|
+
* Drag one up onto the slide or onto a slide card, with a mouse, pen or finger, or tap it to add
|
|
4
|
+
* it to this slide; a check marks those already on it; × deletes a clip; double-click its label
|
|
5
|
+
* to rename it. The strip scrolls sideways; on a touch screen a sideways swipe scrolls and a drag
|
|
6
|
+
* upwards moves the clip.
|
|
7
|
+
*/
|
|
8
|
+
import { type ReactNode } from 'react';
|
|
9
|
+
export declare function ClipTray({ start }: {
|
|
10
|
+
start?: ReactNode;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo, useRef, useState } from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import { Check, X } from "lucide-react";
|
|
6
|
+
import { cn } from "@arbidocs/react/ui";
|
|
7
|
+
import { ClipImage } from "./ClipImage.js";
|
|
8
|
+
import { currentSlide, usePresentation } from "./store.js";
|
|
9
|
+
import { useClipDrag } from "./useClipDrag.js";
|
|
10
|
+
const TILE_HEIGHT = 72;
|
|
11
|
+
const TILE_WIDTH = { min: 56, max: 168 };
|
|
12
|
+
function tileSize(aspect, height = TILE_HEIGHT) {
|
|
13
|
+
const width = Math.min(Math.max(height * aspect, TILE_WIDTH.min), TILE_WIDTH.max);
|
|
14
|
+
return { width, height };
|
|
15
|
+
}
|
|
16
|
+
function Fitted({ clip, box }) {
|
|
17
|
+
const wide = clip.aspect > box.width / box.height;
|
|
18
|
+
const size = wide ? { width: box.width, height: box.width / clip.aspect } : { width: box.height * clip.aspect, height: box.height };
|
|
19
|
+
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none", style: size, children: /* @__PURE__ */ jsx(ClipImage, { clip }) });
|
|
20
|
+
}
|
|
21
|
+
function Label({ clip }) {
|
|
22
|
+
const [editing, setEditing] = useState(false);
|
|
23
|
+
if (editing) {
|
|
24
|
+
return /* @__PURE__ */ jsx(
|
|
25
|
+
"input",
|
|
26
|
+
{
|
|
27
|
+
autoFocus: true,
|
|
28
|
+
defaultValue: clip.caption,
|
|
29
|
+
"aria-label": "Clip label",
|
|
30
|
+
className: "w-full rounded border border-input bg-background px-1 text-[11px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
31
|
+
onBlur: (event) => {
|
|
32
|
+
usePresentation.getState().setCaption(clip.id, event.target.value);
|
|
33
|
+
setEditing(false);
|
|
34
|
+
},
|
|
35
|
+
onKeyDown: (event) => {
|
|
36
|
+
if (event.key === "Enter") event.currentTarget.blur();
|
|
37
|
+
if (event.key === "Escape") setEditing(false);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return /* @__PURE__ */ jsx(
|
|
43
|
+
"button",
|
|
44
|
+
{
|
|
45
|
+
type: "button",
|
|
46
|
+
onDoubleClick: () => setEditing(true),
|
|
47
|
+
title: "Double-click to rename",
|
|
48
|
+
className: "block w-full truncate rounded px-0.5 text-left text-[11px] text-muted-foreground hover:text-foreground",
|
|
49
|
+
children: clip.caption || "Untitled"
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
function TrayTile({ clip, onSlide }) {
|
|
54
|
+
const { place, removeClip } = usePresentation.getState();
|
|
55
|
+
const drag = useClipDrag(clip.id, () => !onSlide && place(clip.id));
|
|
56
|
+
const itemRef = useRef(null);
|
|
57
|
+
const size = tileSize(clip.aspect);
|
|
58
|
+
return /* @__PURE__ */ jsxs(
|
|
59
|
+
"li",
|
|
60
|
+
{
|
|
61
|
+
ref: itemRef,
|
|
62
|
+
className: "group relative flex shrink-0 flex-col gap-1",
|
|
63
|
+
style: { width: size.width },
|
|
64
|
+
"data-testid": `tray-clip-${clip.id}`,
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ jsxs(
|
|
67
|
+
"div",
|
|
68
|
+
{
|
|
69
|
+
className: cn(
|
|
70
|
+
"relative flex cursor-grab touch-pan-x select-none items-center justify-center overflow-hidden rounded-lg border bg-muted active:cursor-grabbing",
|
|
71
|
+
onSlide ? "border-primary/40" : "border-border hover:bg-muted/70",
|
|
72
|
+
drag.ghost && "opacity-40"
|
|
73
|
+
),
|
|
74
|
+
style: { height: size.height },
|
|
75
|
+
...drag.handlers,
|
|
76
|
+
title: onSlide ? "On this slide: drag to place it again" : "Drag onto the slide, or tap to add",
|
|
77
|
+
"data-testid": "tray-clip-handle",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ jsx(Fitted, { clip, box: { width: size.width - 8, height: size.height - 8 } }),
|
|
80
|
+
onSlide && /* @__PURE__ */ jsx(
|
|
81
|
+
"span",
|
|
82
|
+
{
|
|
83
|
+
className: "absolute left-1 top-1 flex size-4 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm",
|
|
84
|
+
"aria-label": "On this slide",
|
|
85
|
+
children: /* @__PURE__ */ jsx(Check, { className: "size-3" })
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
"button",
|
|
93
|
+
{
|
|
94
|
+
type: "button",
|
|
95
|
+
className: "absolute right-1 top-1 flex size-5 items-center justify-center rounded-md bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur-sm transition-opacity hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100 pointer-coarse:size-11 pointer-coarse:opacity-100",
|
|
96
|
+
title: "Delete clip",
|
|
97
|
+
"aria-label": `Delete ${clip.caption || "clip"}`,
|
|
98
|
+
onClick: () => removeClip(clip.id),
|
|
99
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3" })
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
/* @__PURE__ */ jsx(Label, { clip }),
|
|
103
|
+
drag.ghost && createPortal(
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
"div",
|
|
106
|
+
{
|
|
107
|
+
className: "pointer-events-none fixed z-[100] flex -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-lg border border-border bg-card p-1 shadow-xl",
|
|
108
|
+
style: { left: drag.ghost.x, top: drag.ghost.y },
|
|
109
|
+
"data-testid": "tray-drag-ghost",
|
|
110
|
+
children: /* @__PURE__ */ jsx(Fitted, { clip, box: tileSize(clip.aspect, 96) })
|
|
111
|
+
}
|
|
112
|
+
),
|
|
113
|
+
// The tray's own window (the app's, or the presentation pop-out's).
|
|
114
|
+
itemRef.current?.ownerDocument.body ?? document.body
|
|
115
|
+
)
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
function ClipTray({ start }) {
|
|
121
|
+
const all = usePresentation((s) => s.clips);
|
|
122
|
+
const clips = useMemo(() => all.filter((clip) => !clip.plain), [all]);
|
|
123
|
+
const slide = usePresentation(currentSlide);
|
|
124
|
+
const onSlide = new Set(slide?.items.map((item) => item.clipId));
|
|
125
|
+
return /* @__PURE__ */ jsx("div", { className: "shrink-0 border-t border-border bg-background", "data-testid": "clip-tray-bar", children: clips.length || start ? /* @__PURE__ */ jsxs(
|
|
126
|
+
"ul",
|
|
127
|
+
{
|
|
128
|
+
className: "flex items-start gap-2 overflow-x-auto overscroll-x-contain px-3 py-2 [scrollbar-width:none]",
|
|
129
|
+
"aria-label": "Clips",
|
|
130
|
+
"data-testid": "clip-tray",
|
|
131
|
+
children: [
|
|
132
|
+
start && /* @__PURE__ */ jsx("li", { className: "shrink-0", children: start }),
|
|
133
|
+
clips.map((clip) => /* @__PURE__ */ jsx(TrayTile, { clip, onSlide: onSlide.has(clip.id) }, clip.id))
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
) : /* @__PURE__ */ jsxs(
|
|
137
|
+
"p",
|
|
138
|
+
{
|
|
139
|
+
className: "px-4 py-5 text-center text-xs text-muted-foreground",
|
|
140
|
+
"data-testid": "clip-tray-empty",
|
|
141
|
+
children: [
|
|
142
|
+
"Your clips appear here. In a document, choose ",
|
|
143
|
+
/* @__PURE__ */ jsx("strong", { children: "Clip" }),
|
|
144
|
+
" and drag over a page, image or video."
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
) });
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
ClipTray
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=ClipTray.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/ClipTray.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * The clips taken so far, as a strip of tiles along the bottom (the files explorer's tile look).\n * Drag one up onto the slide or onto a slide card, with a mouse, pen or finger, or tap it to add\n * it to this slide; a check marks those already on it; \u00D7 deletes a clip; double-click its label\n * to rename it. The strip scrolls sideways; on a touch screen a sideways swipe scrolls and a drag\n * upwards moves the clip.\n */\n\nimport { useMemo, useRef, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Check, X } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ClipImage } from './ClipImage'\nimport type { Clip } from './model'\nimport { currentSlide, usePresentation } from './store'\nimport { useClipDrag } from './useClipDrag'\n\n/** Tile height (px); its width follows the clip's shape, within these bounds. */\nconst TILE_HEIGHT = 72\nconst TILE_WIDTH = { min: 56, max: 168 }\n\nfunction tileSize(aspect: number, height = TILE_HEIGHT) {\n const width = Math.min(Math.max(height * aspect, TILE_WIDTH.min), TILE_WIDTH.max)\n return { width, height }\n}\n\n/** The clip, fitted in a box, aspect kept. */\nfunction Fitted({ clip, box }: { clip: Clip; box: { width: number; height: number } }) {\n const wide = clip.aspect > box.width / box.height\n const size = wide\n ? { width: box.width, height: box.width / clip.aspect }\n : { width: box.height * clip.aspect, height: box.height }\n return (\n <div className=\"pointer-events-none\" style={size}>\n <ClipImage clip={clip} />\n </div>\n )\n}\n\nfunction Label({ clip }: { clip: Clip }) {\n const [editing, setEditing] = useState(false)\n if (editing) {\n return (\n <input\n autoFocus\n defaultValue={clip.caption}\n aria-label=\"Clip label\"\n className=\"w-full rounded border border-input bg-background px-1 text-[11px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n onBlur={(event) => {\n usePresentation.getState().setCaption(clip.id, event.target.value)\n setEditing(false)\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') event.currentTarget.blur()\n if (event.key === 'Escape') setEditing(false)\n }}\n />\n )\n }\n return (\n <button\n type=\"button\"\n onDoubleClick={() => setEditing(true)}\n title=\"Double-click to rename\"\n className=\"block w-full truncate rounded px-0.5 text-left text-[11px] text-muted-foreground hover:text-foreground\"\n >\n {clip.caption || 'Untitled'}\n </button>\n )\n}\n\nfunction TrayTile({ clip, onSlide }: { clip: Clip; onSlide: boolean }) {\n const { place, removeClip } = usePresentation.getState()\n const drag = useClipDrag(clip.id, () => !onSlide && place(clip.id))\n const itemRef = useRef<HTMLLIElement>(null)\n const size = tileSize(clip.aspect)\n return (\n <li\n ref={itemRef}\n className=\"group relative flex shrink-0 flex-col gap-1\"\n style={{ width: size.width }}\n data-testid={`tray-clip-${clip.id}`}\n >\n <div\n className={cn(\n 'relative flex cursor-grab touch-pan-x select-none items-center justify-center overflow-hidden rounded-lg border bg-muted active:cursor-grabbing',\n onSlide ? 'border-primary/40' : 'border-border hover:bg-muted/70',\n drag.ghost && 'opacity-40'\n )}\n style={{ height: size.height }}\n {...drag.handlers}\n title={\n onSlide ? 'On this slide: drag to place it again' : 'Drag onto the slide, or tap to add'\n }\n data-testid=\"tray-clip-handle\"\n >\n <Fitted clip={clip} box={{ width: size.width - 8, height: size.height - 8 }} />\n {onSlide && (\n <span\n className=\"absolute left-1 top-1 flex size-4 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm\"\n aria-label=\"On this slide\"\n >\n <Check className=\"size-3\" />\n </span>\n )}\n </div>\n <button\n type=\"button\"\n className=\"absolute right-1 top-1 flex size-5 items-center justify-center rounded-md bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur-sm transition-opacity hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100 pointer-coarse:size-11 pointer-coarse:opacity-100\"\n title=\"Delete clip\"\n aria-label={`Delete ${clip.caption || 'clip'}`}\n onClick={() => removeClip(clip.id)}\n >\n <X className=\"size-3\" />\n </button>\n <Label clip={clip} />\n {/* The tile following the pointer while dragging, above everything in its window. */}\n {drag.ghost &&\n createPortal(\n <div\n className=\"pointer-events-none fixed z-[100] flex -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-lg border border-border bg-card p-1 shadow-xl\"\n style={{ left: drag.ghost.x, top: drag.ghost.y }}\n data-testid=\"tray-drag-ghost\"\n >\n <Fitted clip={clip} box={tileSize(clip.aspect, 96)} />\n </div>,\n // The tray's own window (the app's, or the presentation pop-out's).\n itemRef.current?.ownerDocument.body ?? document.body\n )}\n </li>\n )\n}\n\nexport function ClipTray({ start }: { start?: ReactNode }) {\n const all = usePresentation((s) => s.clips)\n // A picture that is part of a slide's design (an imported deck's) is no clip to arrange.\n const clips = useMemo(() => all.filter((clip) => !clip.plain), [all])\n const slide = usePresentation(currentSlide)\n const onSlide = new Set(slide?.items.map((item) => item.clipId))\n return (\n <div className=\"shrink-0 border-t border-border bg-background\" data-testid=\"clip-tray-bar\">\n {clips.length || start ? (\n <ul\n className=\"flex items-start gap-2 overflow-x-auto overscroll-x-contain px-3 py-2 [scrollbar-width:none]\"\n aria-label=\"Clips\"\n data-testid=\"clip-tray\"\n >\n {start && <li className=\"shrink-0\">{start}</li>}\n {clips.map((clip) => (\n <TrayTile key={clip.id} clip={clip} onSlide={onSlide.has(clip.id)} />\n ))}\n </ul>\n ) : (\n <p\n className=\"px-4 py-5 text-center text-xs text-muted-foreground\"\n data-testid=\"clip-tray-empty\"\n >\n Your clips appear here. In a document, choose <strong>Clip</strong> and drag over a page,\n image or video.\n </p>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The selected clip's view controls, on a layer over it (editor only): arrows at the middle of each
|
|
3
|
+
* edge scroll what the clip shows over its source (a press steps, holding keeps scrolling; an arrow
|
|
4
|
+
* at the source's edge is off), and a zoom slider zooms about the clip's centre.
|
|
5
|
+
* The clip's frame on the slide does not change; only the part of the source it shows. Presses
|
|
6
|
+
* here never start moving the clip.
|
|
7
|
+
*/
|
|
8
|
+
import type { Clip } from './model';
|
|
9
|
+
export declare function ClipViewControls({ clip }: {
|
|
10
|
+
clip: Clip;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from "lucide-react";
|
|
5
|
+
import { cn } from "@arbidocs/react/ui";
|
|
6
|
+
import { ZoomSlider } from "../components/ZoomSlider.js";
|
|
7
|
+
import { usePresentation } from "./store.js";
|
|
8
|
+
const PAN_STEP = 0.1;
|
|
9
|
+
const MAX_ZOOM = 800;
|
|
10
|
+
const HOLD_DELAY = 350;
|
|
11
|
+
const HOLD_EVERY = 90;
|
|
12
|
+
const BUTTON = "pointer-events-auto flex size-7 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm backdrop-blur-sm hover:bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-30 pointer-coarse:size-11";
|
|
13
|
+
function HoldButton({
|
|
14
|
+
label,
|
|
15
|
+
disabled,
|
|
16
|
+
onStep,
|
|
17
|
+
className,
|
|
18
|
+
children
|
|
19
|
+
}) {
|
|
20
|
+
const timer = useRef(null);
|
|
21
|
+
const stop = () => {
|
|
22
|
+
if (timer.current) clearTimeout(timer.current);
|
|
23
|
+
timer.current = null;
|
|
24
|
+
};
|
|
25
|
+
useEffect(() => stop, []);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (disabled) stop();
|
|
28
|
+
}, [disabled]);
|
|
29
|
+
const start = (event) => {
|
|
30
|
+
event.stopPropagation();
|
|
31
|
+
if (disabled || event.button !== 0) return;
|
|
32
|
+
onStep();
|
|
33
|
+
const repeat = () => {
|
|
34
|
+
onStep();
|
|
35
|
+
timer.current = setTimeout(repeat, HOLD_EVERY);
|
|
36
|
+
};
|
|
37
|
+
timer.current = setTimeout(repeat, HOLD_DELAY);
|
|
38
|
+
};
|
|
39
|
+
return /* @__PURE__ */ jsx(
|
|
40
|
+
"button",
|
|
41
|
+
{
|
|
42
|
+
type: "button",
|
|
43
|
+
className: cn(BUTTON, className),
|
|
44
|
+
title: label,
|
|
45
|
+
"aria-label": label,
|
|
46
|
+
disabled,
|
|
47
|
+
onPointerDown: start,
|
|
48
|
+
onPointerUp: stop,
|
|
49
|
+
onPointerLeave: stop,
|
|
50
|
+
onPointerCancel: stop,
|
|
51
|
+
onClick: (event) => event.detail === 0 && onStep(),
|
|
52
|
+
children
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
function ClipViewControls({ clip }) {
|
|
57
|
+
const { panClip, setClipZoom } = usePresentation.getState();
|
|
58
|
+
const { rect } = clip;
|
|
59
|
+
const zoomBase = clip.zoomBase ?? rect.w;
|
|
60
|
+
const minZoom = Math.min(100, Math.floor(zoomBase / Math.min(1, rect.w / rect.h) * 100));
|
|
61
|
+
const pan = (dx, dy) => () => panClip(clip.id, dx * rect.w, dy * rect.h);
|
|
62
|
+
const zoom = Math.round(zoomBase / rect.w * 100);
|
|
63
|
+
const edge = 1e-6;
|
|
64
|
+
return /* @__PURE__ */ jsxs(
|
|
65
|
+
"div",
|
|
66
|
+
{
|
|
67
|
+
className: "pointer-events-none absolute inset-0 z-10",
|
|
68
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
69
|
+
"data-testid": "clip-view-controls",
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
HoldButton,
|
|
73
|
+
{
|
|
74
|
+
label: "Show more above",
|
|
75
|
+
disabled: rect.y <= edge,
|
|
76
|
+
onStep: pan(0, -PAN_STEP),
|
|
77
|
+
className: "absolute left-1/2 top-4 -translate-x-1/2 pointer-coarse:top-7",
|
|
78
|
+
children: /* @__PURE__ */ jsx(ChevronUp, { className: "size-4" })
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
/* @__PURE__ */ jsx(
|
|
82
|
+
HoldButton,
|
|
83
|
+
{
|
|
84
|
+
label: "Show more below",
|
|
85
|
+
disabled: rect.y + rect.h >= 1 - edge,
|
|
86
|
+
onStep: pan(0, PAN_STEP),
|
|
87
|
+
className: "absolute bottom-10 left-1/2 -translate-x-1/2 pointer-coarse:bottom-14",
|
|
88
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4" })
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
HoldButton,
|
|
93
|
+
{
|
|
94
|
+
label: "Show more on the left",
|
|
95
|
+
disabled: rect.x <= edge,
|
|
96
|
+
onStep: pan(-PAN_STEP, 0),
|
|
97
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 pointer-coarse:left-7",
|
|
98
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" })
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ jsx(
|
|
102
|
+
HoldButton,
|
|
103
|
+
{
|
|
104
|
+
label: "Show more on the right",
|
|
105
|
+
disabled: rect.x + rect.w >= 1 - edge,
|
|
106
|
+
onStep: pan(PAN_STEP, 0),
|
|
107
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 pointer-coarse:right-7",
|
|
108
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
"div",
|
|
113
|
+
{
|
|
114
|
+
className: "pointer-events-auto absolute bottom-1.5 left-1/2 -translate-x-1/2",
|
|
115
|
+
"data-testid": "clip-zoom-control",
|
|
116
|
+
children: /* @__PURE__ */ jsx(
|
|
117
|
+
ZoomSlider,
|
|
118
|
+
{
|
|
119
|
+
value: zoom,
|
|
120
|
+
min: minZoom,
|
|
121
|
+
max: Math.max(MAX_ZOOM, zoom),
|
|
122
|
+
zoomOutStep: 25,
|
|
123
|
+
onChange: (value) => setClipZoom(clip.id, value),
|
|
124
|
+
label: "Zoom",
|
|
125
|
+
valueLabel: /* @__PURE__ */ jsxs("span", { "data-testid": "clip-zoom", children: [
|
|
126
|
+
zoom,
|
|
127
|
+
"%"
|
|
128
|
+
] }),
|
|
129
|
+
className: "bg-background/95 shadow-sm backdrop-blur-sm pointer-coarse:h-11",
|
|
130
|
+
sliderClassName: "w-24"
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
ClipViewControls
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=ClipViewControls.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/ClipViewControls.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * The selected clip's view controls, on a layer over it (editor only): arrows at the middle of each\n * edge scroll what the clip shows over its source (a press steps, holding keeps scrolling; an arrow\n * at the source's edge is off), and a zoom slider zooms about the clip's centre.\n * The clip's frame on the slide does not change; only the part of the source it shows. Presses\n * here never start moving the clip.\n */\n\nimport { useEffect, useRef, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react'\nimport { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ZoomSlider } from '../components/ZoomSlider'\nimport type { Clip } from './model'\nimport { usePresentation } from './store'\n\n/** One step scrolls this much of what the clip shows. */\nconst PAN_STEP = 0.1\n/** The closest a clip zooms, in percent of how close it was cut. */\nconst MAX_ZOOM = 800\n/** Holding a button repeats it after this long, this often. */\nconst HOLD_DELAY = 350\nconst HOLD_EVERY = 90\n\nconst BUTTON =\n 'pointer-events-auto flex size-7 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm backdrop-blur-sm hover:bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-30 pointer-coarse:size-11'\n\n/** A button that acts on press and keeps acting while held. */\nfunction HoldButton({\n label,\n disabled,\n onStep,\n className,\n children,\n}: {\n label: string\n disabled?: boolean\n onStep: () => void\n className?: string\n children: ReactNode\n}) {\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null)\n const stop = () => {\n if (timer.current) clearTimeout(timer.current)\n timer.current = null\n }\n useEffect(() => stop, [])\n useEffect(() => {\n if (disabled) stop()\n }, [disabled])\n const start = (event: ReactPointerEvent) => {\n event.stopPropagation()\n if (disabled || event.button !== 0) return\n onStep()\n const repeat = () => {\n onStep()\n timer.current = setTimeout(repeat, HOLD_EVERY)\n }\n timer.current = setTimeout(repeat, HOLD_DELAY)\n }\n return (\n <button\n type=\"button\"\n className={cn(BUTTON, className)}\n title={label}\n aria-label={label}\n disabled={disabled}\n onPointerDown={start}\n onPointerUp={stop}\n onPointerLeave={stop}\n onPointerCancel={stop}\n // Keyboard: Enter / Space step once.\n onClick={(event) => event.detail === 0 && onStep()}\n >\n {children}\n </button>\n )\n}\n\nexport function ClipViewControls({ clip }: { clip: Clip }) {\n const { panClip, setClipZoom } = usePresentation.getState()\n const { rect } = clip\n const zoomBase = clip.zoomBase ?? rect.w\n // As far out as it goes: the widest area of this shape the source holds.\n const minZoom = Math.min(100, Math.floor((zoomBase / Math.min(1, rect.w / rect.h)) * 100))\n const pan = (dx: number, dy: number) => () => panClip(clip.id, dx * rect.w, dy * rect.h)\n const zoom = Math.round((zoomBase / rect.w) * 100)\n const edge = 1e-6\n return (\n <div\n className=\"pointer-events-none absolute inset-0 z-10\"\n // A press on the layer is not a press on the clip (which would start moving it).\n onPointerDown={(event) => event.stopPropagation()}\n data-testid=\"clip-view-controls\"\n >\n <HoldButton\n label=\"Show more above\"\n disabled={rect.y <= edge}\n onStep={pan(0, -PAN_STEP)}\n className=\"absolute left-1/2 top-4 -translate-x-1/2 pointer-coarse:top-7\"\n >\n <ChevronUp className=\"size-4\" />\n </HoldButton>\n <HoldButton\n label=\"Show more below\"\n disabled={rect.y + rect.h >= 1 - edge}\n onStep={pan(0, PAN_STEP)}\n className=\"absolute bottom-10 left-1/2 -translate-x-1/2 pointer-coarse:bottom-14\"\n >\n <ChevronDown className=\"size-4\" />\n </HoldButton>\n <HoldButton\n label=\"Show more on the left\"\n disabled={rect.x <= edge}\n onStep={pan(-PAN_STEP, 0)}\n className=\"absolute left-4 top-1/2 -translate-y-1/2 pointer-coarse:left-7\"\n >\n <ChevronLeft className=\"size-4\" />\n </HoldButton>\n <HoldButton\n label=\"Show more on the right\"\n disabled={rect.x + rect.w >= 1 - edge}\n onStep={pan(PAN_STEP, 0)}\n className=\"absolute right-4 top-1/2 -translate-y-1/2 pointer-coarse:right-7\"\n >\n <ChevronRight className=\"size-4\" />\n </HoldButton>\n {/* Zoom: a slider, from as far out as the source allows to MAX_ZOOM. */}\n <div\n className=\"pointer-events-auto absolute bottom-1.5 left-1/2 -translate-x-1/2\"\n data-testid=\"clip-zoom-control\"\n >\n <ZoomSlider\n value={zoom}\n min={minZoom}\n max={Math.max(MAX_ZOOM, zoom)}\n zoomOutStep={25}\n onChange={(value) => setClipZoom(clip.id, value)}\n label=\"Zoom\"\n valueLabel={<span data-testid=\"clip-zoom\">{zoom}%</span>}\n // Over the clip: on the surface colour, so it reads over any content.\n className=\"bg-background/95 shadow-sm backdrop-blur-sm pointer-coarse:h-11\"\n sliderClassName=\"w-24\"\n />\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design: the presentation's one look, for every slide — its background (a preset, or any
|
|
3
|
+
* colour), typeface, accent colour and footer logo. A popover from the header; each choice applies
|
|
4
|
+
* at once (the stage behind it shows the result).
|
|
5
|
+
*/
|
|
6
|
+
export declare function DesignMenu({ onChooseLogo }: {
|
|
7
|
+
onChooseLogo?: () => void;
|
|
8
|
+
}): import("react").JSX.Element;
|