@arbidocs/blocks 0.5.114 → 0.5.116
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/{ConnectedCallDock-2KXEQENS.cjs → ConnectedCallDock-WER7R222.cjs} +21 -21
- package/dist/{ConnectedCallDock-2KXEQENS.cjs.map → ConnectedCallDock-WER7R222.cjs.map} +1 -1
- package/dist/{ConnectedCallRoom-MU3NPNXF.cjs → ConnectedCallRoom-T7OBQTYP.cjs} +14 -14
- package/dist/{ConnectedCallRoom-MU3NPNXF.cjs.map → ConnectedCallRoom-T7OBQTYP.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-VH3I65H6.cjs → ConnectedNativeDocxComparison-546ILGLW.cjs} +19 -19
- package/dist/{ConnectedNativeDocxComparison-VH3I65H6.cjs.map → ConnectedNativeDocxComparison-546ILGLW.cjs.map} +1 -1
- package/dist/{ConnectedProductionSetDialog-4EAY6KAZ.cjs → ConnectedProductionSetDialog-LHB4VQWC.cjs} +3 -3
- package/dist/{ConnectedProductionSetDialog-4EAY6KAZ.cjs.map → ConnectedProductionSetDialog-LHB4VQWC.cjs.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-KQSHCA75.cjs → ConnectedStreamedWordArtifact-S2ZFZLZQ.cjs} +19 -19
- package/dist/{ConnectedStreamedWordArtifact-KQSHCA75.cjs.map → ConnectedStreamedWordArtifact-S2ZFZLZQ.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-OCPFVMLD.cjs → DocumentReviewCard-ZSBZBGFK.cjs} +15 -15
- package/dist/{DocumentReviewCard-OCPFVMLD.cjs.map → DocumentReviewCard-ZSBZBGFK.cjs.map} +1 -1
- package/dist/{FilesViewerDialog-BAGOEMXW.cjs → FilesViewerDialog-6UKR5WEF.cjs} +44 -44
- package/dist/{FilesViewerDialog-BAGOEMXW.cjs.map → FilesViewerDialog-6UKR5WEF.cjs.map} +1 -1
- package/dist/{NativeDocxEditor-EJEIJDOC.cjs → NativeDocxEditor-2LQY2CTV.cjs} +6 -6
- package/dist/{NativeDocxEditor-EJEIJDOC.cjs.map → NativeDocxEditor-2LQY2CTV.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-IMAZICIZ.cjs → WorkspaceTableView-J3C6VH4T.cjs} +8 -8
- package/dist/{WorkspaceTableView-IMAZICIZ.cjs.map → WorkspaceTableView-J3C6VH4T.cjs.map} +1 -1
- package/dist/agents/index.cjs +297 -297
- package/dist/{ai-7U4B4CVF.cjs → ai-IM4A23YT.cjs} +24 -24
- package/dist/ai-IM4A23YT.cjs.map +1 -0
- package/dist/calls/index.cjs +121 -121
- package/dist/chat/DraftingDocChip.d.ts +3 -1
- package/dist/chat/DraftingDocChip.js +7 -4
- package/dist/chat/DraftingDocChip.js.map +2 -2
- package/dist/chat/index.cjs +37 -37
- package/dist/{chunk-4ED7CNOX.cjs → chunk-2CSLFAGF.cjs} +430 -150
- package/dist/chunk-2CSLFAGF.cjs.map +1 -0
- package/dist/{chunk-Q6DQGGP4.cjs → chunk-325GVZE6.cjs} +3 -3
- package/dist/{chunk-Q6DQGGP4.cjs.map → chunk-325GVZE6.cjs.map} +1 -1
- package/dist/{chunk-LFRNBT2I.cjs → chunk-557MJ4IH.cjs} +20 -20
- package/dist/{chunk-LFRNBT2I.cjs.map → chunk-557MJ4IH.cjs.map} +1 -1
- package/dist/{chunk-JSQQV23D.cjs → chunk-6UTKM5AB.cjs} +3 -3
- package/dist/{chunk-JSQQV23D.cjs.map → chunk-6UTKM5AB.cjs.map} +1 -1
- package/dist/{chunk-H5OLHP2U.cjs → chunk-7OPOPYV6.cjs} +3 -3
- package/dist/{chunk-H5OLHP2U.cjs.map → chunk-7OPOPYV6.cjs.map} +1 -1
- package/dist/{chunk-AHT6DQNI.cjs → chunk-B2HNNG25.cjs} +50 -50
- package/dist/{chunk-AHT6DQNI.cjs.map → chunk-B2HNNG25.cjs.map} +1 -1
- package/dist/{chunk-WW6LXQY6.cjs → chunk-B3LZITVF.cjs} +12 -12
- package/dist/{chunk-WW6LXQY6.cjs.map → chunk-B3LZITVF.cjs.map} +1 -1
- package/dist/{chunk-V5IMYLYK.cjs → chunk-BQ5RIWWT.cjs} +3 -3
- package/dist/{chunk-V5IMYLYK.cjs.map → chunk-BQ5RIWWT.cjs.map} +1 -1
- package/dist/{chunk-INEPPS4H.cjs → chunk-COD5ENHK.cjs} +4 -4
- package/dist/{chunk-INEPPS4H.cjs.map → chunk-COD5ENHK.cjs.map} +1 -1
- package/dist/{chunk-MC4F2URI.cjs → chunk-CPG7II4E.cjs} +28 -28
- package/dist/{chunk-MC4F2URI.cjs.map → chunk-CPG7II4E.cjs.map} +1 -1
- package/dist/{chunk-7XT5B2DZ.cjs → chunk-CPR6EHG7.cjs} +47 -47
- package/dist/{chunk-7XT5B2DZ.cjs.map → chunk-CPR6EHG7.cjs.map} +1 -1
- package/dist/{chunk-3U36VYMD.cjs → chunk-DDIW4HLU.cjs} +27 -27
- package/dist/{chunk-3U36VYMD.cjs.map → chunk-DDIW4HLU.cjs.map} +1 -1
- package/dist/chunk-HB2O4THB.cjs +18 -0
- package/dist/{chunk-ZZA756I4.cjs.map → chunk-HB2O4THB.cjs.map} +1 -1
- package/dist/{chunk-IFOGBMAE.cjs → chunk-KLMNCBLY.cjs} +9 -6
- package/dist/chunk-KLMNCBLY.cjs.map +1 -0
- package/dist/{chunk-TDN33HSK.cjs → chunk-KTQOGT2L.cjs} +6 -6
- package/dist/{chunk-TDN33HSK.cjs.map → chunk-KTQOGT2L.cjs.map} +1 -1
- package/dist/{chunk-UUENH4BJ.cjs → chunk-KXIRVKCJ.cjs} +3 -3
- package/dist/{chunk-UUENH4BJ.cjs.map → chunk-KXIRVKCJ.cjs.map} +1 -1
- package/dist/{chunk-436I7PQL.cjs → chunk-NIE3N6OM.cjs} +9 -9
- package/dist/{chunk-436I7PQL.cjs.map → chunk-NIE3N6OM.cjs.map} +1 -1
- package/dist/{chunk-XKDUPU7B.cjs → chunk-NJCK6V6U.cjs} +4 -4
- package/dist/{chunk-XKDUPU7B.cjs.map → chunk-NJCK6V6U.cjs.map} +1 -1
- package/dist/{chunk-5QUL5BZO.cjs → chunk-NNUK5ZM7.cjs} +4 -4
- package/dist/{chunk-5QUL5BZO.cjs.map → chunk-NNUK5ZM7.cjs.map} +1 -1
- package/dist/{chunk-4NPCDS2X.cjs → chunk-NY3YUCOW.cjs} +3 -3
- package/dist/{chunk-4NPCDS2X.cjs.map → chunk-NY3YUCOW.cjs.map} +1 -1
- package/dist/{chunk-6DCIZA3X.cjs → chunk-OEREKAAP.cjs} +75 -75
- package/dist/{chunk-6DCIZA3X.cjs.map → chunk-OEREKAAP.cjs.map} +1 -1
- package/dist/{chunk-3ODEWSRO.cjs → chunk-P77YTTJ3.cjs} +4 -4
- package/dist/{chunk-3ODEWSRO.cjs.map → chunk-P77YTTJ3.cjs.map} +1 -1
- package/dist/{chunk-3R6YHJ3G.cjs → chunk-QHOHDNBU.cjs} +6 -6
- package/dist/{chunk-3R6YHJ3G.cjs.map → chunk-QHOHDNBU.cjs.map} +1 -1
- package/dist/{chunk-LYTIQQQ2.cjs → chunk-R7CJEIA5.cjs} +3 -3
- package/dist/{chunk-LYTIQQQ2.cjs.map → chunk-R7CJEIA5.cjs.map} +1 -1
- package/dist/{chunk-MGQSLMTC.cjs → chunk-SB4M3ITT.cjs} +239 -85
- package/dist/chunk-SB4M3ITT.cjs.map +1 -0
- package/dist/{chunk-2W5E62EY.cjs → chunk-SGYSDABK.cjs} +6 -6
- package/dist/{chunk-2W5E62EY.cjs.map → chunk-SGYSDABK.cjs.map} +1 -1
- package/dist/{chunk-UNDQYTRF.cjs → chunk-T23UTIRI.cjs} +6 -6
- package/dist/{chunk-UNDQYTRF.cjs.map → chunk-T23UTIRI.cjs.map} +1 -1
- package/dist/{chunk-E4BLRF2L.cjs → chunk-TDO5UWXF.cjs} +5 -5
- package/dist/{chunk-E4BLRF2L.cjs.map → chunk-TDO5UWXF.cjs.map} +1 -1
- package/dist/{chunk-4IOYQLKG.cjs → chunk-TP5PGWIO.cjs} +3 -3
- package/dist/{chunk-4IOYQLKG.cjs.map → chunk-TP5PGWIO.cjs.map} +1 -1
- package/dist/{chunk-7X3FS5HQ.cjs → chunk-TT4IF52H.cjs} +35 -35
- package/dist/{chunk-7X3FS5HQ.cjs.map → chunk-TT4IF52H.cjs.map} +1 -1
- package/dist/{chunk-NHHEMBXQ.cjs → chunk-VGCTYTEW.cjs} +22 -14
- package/dist/chunk-VGCTYTEW.cjs.map +1 -0
- package/dist/{chunk-HM5L4SBC.cjs → chunk-VKH3BEZE.cjs} +3 -3
- package/dist/{chunk-HM5L4SBC.cjs.map → chunk-VKH3BEZE.cjs.map} +1 -1
- package/dist/{chunk-GQXPNIRE.cjs → chunk-WAV762GP.cjs} +6 -6
- package/dist/{chunk-GQXPNIRE.cjs.map → chunk-WAV762GP.cjs.map} +1 -1
- package/dist/{chunk-MZ2KZXNU.cjs → chunk-WXUU3COI.cjs} +3 -3
- package/dist/{chunk-MZ2KZXNU.cjs.map → chunk-WXUU3COI.cjs.map} +1 -1
- package/dist/{chunk-BW5MF464.cjs → chunk-XKVPSOKP.cjs} +4 -4
- package/dist/{chunk-BW5MF464.cjs.map → chunk-XKVPSOKP.cjs.map} +1 -1
- package/dist/{chunk-57EE6CMW.cjs → chunk-Y24V6HPR.cjs} +15 -15
- package/dist/{chunk-57EE6CMW.cjs.map → chunk-Y24V6HPR.cjs.map} +1 -1
- package/dist/{chunk-ET3NVY27.cjs → chunk-YGBHY67W.cjs} +5 -5
- package/dist/{chunk-ET3NVY27.cjs.map → chunk-YGBHY67W.cjs.map} +1 -1
- package/dist/{chunk-7TEUGFIL.cjs → chunk-YGXOKB5Z.cjs} +4 -4
- package/dist/{chunk-7TEUGFIL.cjs.map → chunk-YGXOKB5Z.cjs.map} +1 -1
- package/dist/connect/docx.cjs +23 -23
- package/dist/connect/index.cjs +1231 -1069
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/viewer.cjs +33 -33
- package/dist/connection/conversation/ConnectedConversation.js +143 -55
- package/dist/connection/conversation/ConnectedConversation.js.map +2 -2
- package/dist/connection/conversation/ConversationSendButton.d.ts +1 -0
- package/dist/connection/conversation/ConversationSendButton.js +3 -2
- package/dist/connection/conversation/ConversationSendButton.js.map +2 -2
- package/dist/connection/conversation/DocumentTargetNotice.d.ts +7 -0
- package/dist/connection/conversation/DocumentTargetNotice.js +45 -0
- package/dist/connection/conversation/DocumentTargetNotice.js.map +7 -0
- package/dist/connection/conversation/documentSwitch.d.ts +9 -0
- package/dist/connection/conversation/documentSwitch.js +40 -0
- package/dist/connection/conversation/documentSwitch.js.map +7 -0
- package/dist/connection/docx/ConnectedNativeDocxEditor.js +10 -2
- package/dist/connection/docx/ConnectedNativeDocxEditor.js.map +2 -2
- package/dist/connection/viewer/ConnectedDocumentViewer.js +124 -21
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/VersionDropdown.d.ts +9 -0
- package/dist/connection/viewer/VersionDropdown.js +39 -0
- package/dist/connection/viewer/VersionDropdown.js.map +7 -0
- package/dist/connection/viewer/ViewerPdfPane.js +4 -1
- package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
- package/dist/connection/viewer/useViewerBlobs.d.ts +3 -1
- package/dist/connection/viewer/useViewerBlobs.js +14 -8
- package/dist/connection/viewer/useViewerBlobs.js.map +2 -2
- package/dist/connection/viewer/useViewerTabs.js +10 -0
- package/dist/connection/viewer/useViewerTabs.js.map +2 -2
- package/dist/dashboards/index.cjs +1 -1
- package/dist/docx/DocxCommandMenu.d.ts +8 -0
- package/dist/docx/DocxCommandMenu.js +202 -0
- package/dist/docx/DocxCommandMenu.js.map +7 -0
- package/dist/docx/NativeDocxEditor.d.ts +4 -2
- package/dist/docx/NativeDocxEditor.js +54 -13
- package/dist/docx/NativeDocxEditor.js.map +2 -2
- package/dist/docx/RibbonMenu.d.ts +3 -1
- package/dist/docx/RibbonMenu.js +10 -3
- package/dist/docx/RibbonMenu.js.map +2 -2
- package/dist/docx/RibbonOverflow.d.ts +3 -0
- package/dist/docx/RibbonOverflow.js +24 -1
- package/dist/docx/RibbonOverflow.js.map +2 -2
- package/dist/docx/index.cjs +38 -38
- package/dist/docx/signatures/SignatureFields.d.ts +5 -1
- package/dist/docx/signatures/SignatureFields.js +57 -10
- package/dist/docx/signatures/SignatureFields.js.map +2 -2
- package/dist/embed/index.cjs +38 -38
- package/dist/files/index.cjs +224 -224
- package/dist/index.cjs +1731 -1731
- package/dist/settings/index.cjs +147 -147
- package/dist/shell/index.cjs +90 -90
- package/dist/site/index.cjs +5 -5
- package/dist/studio/index.cjs +27 -27
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +54 -54
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/src/docx/styles.css +94 -0
- package/dist/ai-7U4B4CVF.cjs.map +0 -1
- package/dist/chunk-4ED7CNOX.cjs.map +0 -1
- package/dist/chunk-IFOGBMAE.cjs.map +0 -1
- package/dist/chunk-MGQSLMTC.cjs.map +0 -1
- package/dist/chunk-NHHEMBXQ.cjs.map +0 -1
- package/dist/chunk-ZZA756I4.cjs +0 -18
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/docx/NativeDocxEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["import { normalizeDocxExport } from './export'\nimport { WordDraftStream } from './streamWordDocument'\nimport {\n DocxMentions,\n DocxCommentActivity,\n type DocxMention,\n type DocxAgentCommentRequest,\n type DocxMentionDelivery,\n type DocxAgentRunStatus,\n} from './DocxMentions'\nimport * as Y from 'yjs'\nimport type { DocumentHandle } from '@docx-editor.dev/core'\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport {\n DocxEditor,\n useChromeTranslate,\n useDocxEditor,\n type FontConfiguration,\n} from '@docx-editor.dev/react'\nimport { collaborationModule, DOCUMENT_COLLABORATION_VERSIONS } from '@arbidocs/coedit'\nimport { awaitMatchingEditor } from './coedit-update'\nimport type { DocxCollaborationSession } from '@arbidocs/coedit'\nimport {\n createHocuspocusCollaboration,\n type HocuspocusCollaborationRoom,\n} from '@arbidocs/coedit/hocuspocus'\nimport { DocxEditorReview, reviewModule } from './review'\nimport { AgentUndo, AgentUndoRoom } from './AgentUndo'\nimport type { EditorModule } from '@docx-editor.dev/core'\nimport type { Editor } from '@docx-editor.dev/core'\nimport {\n Download,\n Save,\n RefreshCw,\n WifiOff,\n Check,\n Type,\n Pilcrow,\n UsersRound,\n BookA,\n} from 'lucide-react'\nimport { DefinedTermsProvider, useDefinedTerms } from './definitions/DefinedTerms'\nimport { RibbonMenu } from './RibbonMenu'\nimport { RibbonItem, RibbonOverflow } from './RibbonOverflow'\nimport { StyleGallery } from './StyleGallery'\nimport { NoteButtons, WordShortcuts } from './WordReferences'\nimport type { DefinitionSource } from '../tags/definitions'\nimport { CrossReferencesProvider, type DocxReferencesAdapter } from './references/CrossReferences'\nimport {\n CrossReferenceButton,\n DocxContextMenuExtras,\n UpdateCrossReferencesButton,\n} from './references/EditorMenus'\nimport { runBeforeSave } from './beforeSave'\nimport { LayoutTabContent, LAYOUT_TAB, useContextualTabs } from './layout/LayoutTabs'\nimport {\n GenerateImageButton,\n useGenerateImageTarget,\n type DocxImageGeneration,\n} from './layout/GenerateImage'\nimport { TableTabKeys } from './layout/TableKeys'\nimport { newFromTemplate } from '@arbidocs/coedit/template'\nimport {\n HouseTemplateProvider,\n resolveHouseTemplate,\n templateFileName,\n type HouseTemplateHost,\n} from './template/HouseTemplate'\nimport { QuickParts } from './template/QuickParts'\nimport {\n MySignatureContextItems,\n MySignatureMenu,\n SignatureFieldMenu,\n SignatureFieldsProvider,\n type DocxSavedSignature,\n type DocxSigner,\n} from './signatures/SignatureFields'\nimport { HouseTemplatePanel } from './template/HouseTemplatePanel'\nimport { DocxAuthorContext } from './structural/useTrackedOrNoted'\n\nimport { contentPath } from './content-path'\n\nexport { contentPath }\n\n/** Host integration: no application store, router, or authentication singleton is required. */\nexport interface NativeDocxAdapter {\n request: (path: string, options?: RequestInit) => Promise<Response>\n open: (documentId: string) => Promise<{\n room_id: string\n token: string\n websocket_path: string\n can_edit: boolean\n identity: { actorId: string; name: string; role: 'human' | 'agent' }\n filename: string\n }>\n /** Save the live room as the document's next version (same document id). */\n save: (\n documentId: string,\n state?: string\n ) => Promise<{ document_ext_id: string; version?: number; unchanged?: boolean }>\n loadFonts: () => Promise<FontConfiguration>\n baseUrl?: string\n author?: string\n subscribeTokenChanges?: (listener: () => void) => () => void\n onDirtyChange?: (dirty: boolean) => void\n onVersionSaved?: (documentId: string) => void | Promise<void>\n notify?: (message: string, kind: 'success' | 'error') => void\n mentions?: readonly DocxMention[]\n requestAgent?: (\n documentId: string,\n request: DocxAgentCommentRequest\n ) => Promise<DocxMentionDelivery | void>\n getAgentStatus?: (responseId: string) => Promise<DocxAgentRunStatus>\n /**\n * The workspace's definitions: facts labelled \"Definitions\". Present: the Insert tab offers\n * Defined term, and typing `@@` in the body opens the term type-ahead.\n */\n definitions?: () => Promise<DefinitionSource[]>\n /**\n * References to the workspace's other documents. Present: Insert cross-reference also offers a\n * passage of another document, inserted as a link that opens it there.\n */\n references?: DocxReferencesAdapter\n /** The platform's image generation. Present: the Insert tab offers Generate image. */\n imageGeneration?: DocxImageGeneration\n /**\n * The workspace's house template. Present: a blank note starts from it (its styles, numbering,\n * page setup, headers and footers), Insert offers its Quick Parts, and the Design tab and the\n * style box show where the document's styles differ from it.\n */\n houseTemplate?: HouseTemplateHost\n /** Workspace members who may sign. Present: Insert offers Signature field (or anyone by email). */\n signatureSigners?: readonly DocxSigner[]\n /** One's saved signature. Present: Insert offers My signature (an informal one, as a picture). */\n savedSignature?: DocxSavedSignature\n}\n\nexport interface NativeDocxEditorProps {\n adapter: NativeDocxAdapter\n documentId: string\n title: string\n draftContent?: string\n initialCommentId?: string\n /** Immutable history/compare snapshots must not join the live editing room. */\n snapshot?: boolean\n onSaved?: (id: string) => void\n /**\n * Read-only preview of generated Markdown. The server stores the DOCX itself; when the\n * stream ends the caller swaps this preview for the stored document.\n */\n stream?: {\n content: string\n busy: boolean\n error?: string | null\n }\n /**\n * Embedded as a body field (an email draft): a small formatting toolbar instead of the ribbon, no\n * page furniture or save bar (the host saves), and the person types directly; others' edits (ARBI's)\n * still arrive as tracked changes to accept or reject.\n */\n compact?: boolean\n /** Receives a reader of the live room's state, so the host's save can include the latest keystrokes. */\n stateRef?: React.MutableRefObject<(() => string | undefined) | null>\n}\ninterface Ready {\n document: DocumentHandle | Uint8Array\n modules: readonly EditorModule[]\n fonts: FontConfiguration\n room?: HocuspocusCollaborationRoom\n canEdit: boolean\n author: string\n filename: string\n}\n// Local unsaved notes survive tab switches. Persisted artifacts use server state.\nconst drafts = new Map<string, ArrayBuffer>()\nconst stateBytes = (room: HocuspocusCollaborationRoom) => Y.encodeStateAsUpdate(room.ydoc)\nconst encodeState = (room: HocuspocusCollaborationRoom) => {\n let binary = ''\n for (const byte of stateBytes(room)) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\nfunction covered(room: HocuspocusCollaborationRoom, vector: string, receipt: string) {\n const decode = (value: string) => Uint8Array.from(atob(value), (c) => c.charCodeAt(0))\n const server = Y.decodeStateVector(decode(vector)),\n local = Y.decodeStateVector(Y.encodeStateVector(room.ydoc))\n for (const [client, clock] of local) if ((server.get(client) || 0) < clock) return false\n const deleted = Y.decodeUpdate(stateBytes(room)).ds.clients\n const saved = Y.decodeUpdate(decode(receipt)).ds.clients\n for (const [client, ranges] of deleted)\n for (const range of ranges) {\n if (\n !(saved.get(client) || []).some(\n (s) => s.clock <= range.clock && s.clock + s.len >= range.clock + range.len\n )\n )\n return false\n }\n return true\n}\nclass EditorBoundary extends React.Component<{ children: React.ReactNode }, { error?: Error }> {\n state: { error?: Error } = {}\n static getDerivedStateFromError(error: Error) {\n return { error }\n }\n render() {\n return this.state.error ? (\n <div role=\"alert\" className=\"native-docx-error\">\n Could not render this Word document: {this.state.error.message}\n </div>\n ) : (\n this.props.children\n )\n }\n}\n/**\n * The room writes below the editor's input buffer, so it gets the editor's pending-input flush: it\n * lands queued typing before a peer's change and lays that change out at once, which is when the\n * editor carries its caret (otherwise a fast keystroke lands where the caret was before the change).\n */\nfunction RoomInputBinding({ session }: { session?: DocxCollaborationSession }) {\n const editor = useDocxEditor()\n useEffect(() => {\n if (!editor || !session) return\n return session.bindEditorInput(() => editor.surface?.flushPendingInput())\n }, [editor, session])\n return null\n}\n\nexport function DocxParticipants({ session }: { session?: DocxCollaborationSession }) {\n const [people, setPeople] = useState<readonly { actorId: string; name: string }[]>([])\n useEffect(() => {\n if (!session) return\n setPeople(session.participants())\n return session.subscribeParticipants(setPeople)\n }, [session])\n return (\n <div className=\"native-docx-presence\" aria-label=\"People viewing this document\">\n {people.map((p) => (\n <span className=\"native-docx-avatar\" key={p.actorId} title={p.name}>\n {p.name\n .split(' ')\n .map((s) => s[0])\n .slice(0, 2)\n .join('')}\n </span>\n ))}\n </div>\n )\n}\n\n/** Insert tab: a defined term at the caret (when definitions are offered). */\nfunction DefinedTermButtons() {\n const terms = useDefinedTerms()\n if (!terms) return null\n return (\n <button\n type=\"button\"\n className=\"native-docx-ribbon-trigger\"\n aria-label={terms.labels.insert}\n title={`${terms.labels.insert} (type @@)`}\n data-testid=\"docx-insert-defined-term\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => terms.openPicker(event.currentTarget)}\n >\n <BookA size={16} />\n </button>\n )\n}\n\nconst DOCUMENT_STATES = {\n 'co-editing': {\n label: 'Co-editing',\n title: 'Edits sync live with everyone who has this document open',\n },\n 'read-only': {\n label: 'Read-only',\n title: 'This copy cannot be edited: an earlier version, or the last saved copy',\n },\n draft: { label: 'Private draft', title: 'Only you can see this until you save it' },\n} as const\n\n/** Which document is on screen: shared live, read-only, or a draft only its author sees. */\nfunction DocumentStateBadge({ state }: { state?: keyof typeof DOCUMENT_STATES }) {\n if (!state) return null\n const { label, title } = DOCUMENT_STATES[state]\n return (\n <span data-state={state} title={title}>\n {label}\n </span>\n )\n}\n\nexport function DocxRibbon({\n onSave,\n badge,\n imageGeneration,\n}: {\n onSave: () => void\n /** Insert \u203A Generate image, when the host can generate images. */\n imageGeneration?: DocxImageGeneration\n /** A short state label at the end of the row, such as \"Co-editing\". */\n badge?: React.ReactNode\n}) {\n const [selected, setTab] = useState('Home')\n const contextual = useContextualTabs(selected)\n useGenerateImageTarget()\n const tab = contextual.shown\n const t = useChromeTranslate()\n return (\n <div className=\"native-docx-ribbon\">\n <select aria-label=\"Ribbon tab\" value={tab} onChange={(event) => setTab(event.target.value)}>\n <option>Home</option>\n <option>Insert</option>\n <option>Design</option>\n <option>{LAYOUT_TAB}</option>\n <option>References</option>\n <option>Review</option>\n {contextual.tabs.map((name) => (\n <option key={name}>{name}</option>\n ))}\n </select>\n <DocxEditor.Toolbar t={t} preset={false} onSave={onSave}>\n <DocxEditor.Toolbar.Undo />\n <DocxEditor.Toolbar.Redo />\n <DocxEditor.Toolbar.Save />\n {/* Undo, Redo and Save stay put, like Word's Quick Access Toolbar; the tab's own\n controls collapse into its More menu when the ribbon is too narrow for them. */}\n <RibbonOverflow tab={tab}>\n {tab === 'Home' && (\n <>\n <RibbonItem id=\"home-style\" label=\"Styles\" priority={80}>\n <StyleGallery />\n </RibbonItem>\n <RibbonItem id=\"home-bold\" label=\"Bold\" priority={100}>\n <DocxEditor.Toolbar.Bold />\n </RibbonItem>\n <RibbonItem id=\"home-italic\" label=\"Italic\" priority={95}>\n <DocxEditor.Toolbar.Italic />\n </RibbonItem>\n <RibbonItem id=\"home-underline\" label=\"Underline\" priority={90}>\n <DocxEditor.Toolbar.Underline />\n </RibbonItem>\n <RibbonItem id=\"home-font\" label=\"Font\" priority={60}>\n <RibbonMenu label=\"Font\" icon={<Type size={16} />}>\n <DocxEditor.Toolbar.FontFamily />\n <DocxEditor.Toolbar.FontSize />\n <DocxEditor.Toolbar.FontColor />\n <DocxEditor.Toolbar.Highlight />\n </RibbonMenu>\n </RibbonItem>\n <RibbonItem id=\"home-more-formatting\" label=\"More formatting\" priority={50}>\n <RibbonMenu label=\"More formatting\" icon={<Pilcrow size={16} />}>\n <DocxEditor.Toolbar.Alignment />\n <DocxEditor.Toolbar.BulletList />\n <DocxEditor.Toolbar.NumberedList />\n <DocxEditor.Toolbar.LineSpacing />\n <DocxEditor.Toolbar.Indent />\n <DocxEditor.Toolbar.Outdent />\n <DocxEditor.Toolbar.Strike />\n <DocxEditor.Toolbar.ClearFormatting />\n </RibbonMenu>\n </RibbonItem>\n </>\n )}\n {tab === 'Insert' && (\n <>\n <RibbonItem id=\"insert-table\" label=\"Table\">\n <DocxEditor.Toolbar.TableInsert />\n </RibbonItem>\n <RibbonItem id=\"insert-picture\" label=\"Picture\">\n <DocxEditor.Toolbar.ImageInsert />\n </RibbonItem>\n {imageGeneration && (\n <RibbonItem id=\"insert-generate-image\" label=\"Generate image\">\n <GenerateImageButton generation={imageGeneration} />\n </RibbonItem>\n )}\n <RibbonItem id=\"insert-page-break\" label=\"Page break\">\n <DocxEditor.Toolbar.Button slotId=\"insert.pageBreak\" />\n </RibbonItem>\n <RibbonItem id=\"insert-link\" label=\"Link\">\n <DocxEditor.Toolbar.Link />\n </RibbonItem>\n <RibbonItem id=\"insert-defined-term\" label=\"Defined term\">\n <DefinedTermButtons />\n </RibbonItem>\n <RibbonItem id=\"insert-quick-parts\" label=\"Quick Parts\">\n <QuickParts />\n </RibbonItem>\n <RibbonItem id=\"insert-signature-field\" label=\"Signature field\">\n <SignatureFieldMenu />\n </RibbonItem>\n <RibbonItem id=\"insert-my-signature\" label=\"My signature\">\n <MySignatureMenu />\n </RibbonItem>\n <RibbonItem id=\"insert-cross-reference\" label=\"Cross-reference\">\n <CrossReferenceButton />\n </RibbonItem>\n </>\n )}\n <LayoutTabContent tab={tab} />\n {tab === 'Design' && (\n <RibbonItem id=\"design-house-template\" label=\"House template\">\n <HouseTemplatePanel />\n </RibbonItem>\n )}\n {tab === 'References' && (\n <>\n <NoteButtons />\n <RibbonItem id=\"references-cross-reference\" label=\"Cross-reference\">\n <CrossReferenceButton />\n </RibbonItem>\n <RibbonItem id=\"references-update-cross-references\" label=\"Update cross-references\">\n <UpdateCrossReferencesButton />\n </RibbonItem>\n </>\n )}\n {tab === 'Review' && (\n <>\n <RibbonItem id=\"review-editing-mode\" label=\"Editing mode\" priority={10}>\n <DocxEditor.Toolbar.EditingMode />\n </RibbonItem>\n <RibbonItem id=\"review-comments\" label=\"Comments\">\n <DocxEditor.Toolbar.Comments />\n </RibbonItem>\n <RibbonItem id=\"review-options\" label=\"Review options\">\n <RibbonMenu label=\"Review options\" icon={<UsersRound size={16} />}>\n <DocxEditor.Toolbar.Reviewers />\n </RibbonMenu>\n </RibbonItem>\n </>\n )}\n </RibbonOverflow>\n {/* The toolbar provides its table chrome context only to a direct table-chrome child: this\n hidden one keeps it mounted for the Table tab's borders and shading. */}\n <DocxEditor.Toolbar.TableCellFill hidden />\n </DocxEditor.Toolbar>\n {badge && (\n <span className=\"native-docx-ribbon-badge\" data-testid=\"docx-ribbon-badge\">\n {badge}\n </span>\n )}\n </div>\n )\n}\n\n/** The compact editor's formatting: what an email needs. */\nfunction CompactToolbar() {\n const t = useChromeTranslate()\n return (\n <DocxEditor.Toolbar t={t} preset={false}>\n <DocxEditor.Toolbar.Undo />\n <DocxEditor.Toolbar.Redo />\n <DocxEditor.Toolbar.Bold />\n <DocxEditor.Toolbar.Italic />\n <DocxEditor.Toolbar.Underline />\n <DocxEditor.Toolbar.BulletList />\n <DocxEditor.Toolbar.NumberedList />\n <DocxEditor.Toolbar.Link />\n </DocxEditor.Toolbar>\n )\n}\n\nconst fixedZoomMode = { type: 'fixed' } as const\n/** The zoom menu's levels, in percent, beside Fit width. */\nconst ZOOM_LEVELS = [50, 75, 100, 125, 150, 200]\n\nexport function NativeDocxEditor({\n documentId,\n title,\n draftContent,\n initialCommentId,\n snapshot = false,\n onSaved,\n stream,\n adapter,\n compact = false,\n stateRef,\n}: NativeDocxEditorProps) {\n const [ready, setReady] = useState<Ready>(),\n [error, setError] = useState(''),\n [retry, setRetry] = useState(0)\n const [status, setStatus] = useState('Connecting\u2026'),\n [dirty, setDirty] = useState(false),\n [saving, setSaving] = useState(false),\n [offline, setOffline] = useState(false)\n const revision = useRef(0)\n const stageRef = useRef<HTMLDivElement>(null),\n fitCleanup = useRef<(() => void) | undefined>(undefined),\n refit = useRef<(() => void) | undefined>(undefined)\n // Fit width until the reader picks a zoom (the zoom menu, or Ctrl +/-/0), then keep theirs until\n // they pick Fit width again. `fitted` is the zoom the fit last applied: any other zoom is theirs.\n const fitting = useRef(true),\n fitted = useRef<number | undefined>(undefined)\n const [fitWidth, setFitWidth] = useState(true),\n [zoomPercent, setZoomPercent] = useState(100)\n const ref = useRef<Editor | null>(null),\n dirtyRef = useRef(false),\n draftTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const isDraft = draftContent !== undefined\n const streamRef = useRef(stream)\n streamRef.current = stream\n const streamWriter = useRef<WordDraftStream | null>(null)\n const streamFinished = useRef(false)\n const streamTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const [streamAttempt, setStreamAttempt] = useState(0)\n function updateStream() {\n const current = streamRef.current\n if (!current || !streamWriter.current || streamFinished.current) return\n try {\n streamWriter.current.update(current.content, !current.busy)\n setStatus(\n current.busy\n ? 'Generating \u00B7 editing is locked'\n : current.error\n ? 'Generation stopped \u00B7 draft retained'\n : 'Opening the saved document\u2026'\n )\n if (!current.busy && !current.error) streamFinished.current = true\n } catch (failure) {\n setError(\n failure instanceof Error ? failure.message : 'Could not import the generated document.'\n )\n }\n }\n useEffect(() => {\n if (!streamRef.current) return\n if (!streamRef.current.busy) {\n clearTimeout(streamTimer.current)\n streamTimer.current = undefined\n updateStream()\n } else if (!streamTimer.current) {\n streamTimer.current = setTimeout(() => {\n streamTimer.current = undefined\n updateStream()\n }, 120)\n }\n }, [stream?.content, stream?.busy, stream?.error, streamAttempt])\n useEffect(() => () => clearTimeout(streamTimer.current), [])\n useEffect(() => {\n let cancelled = false\n let room: HocuspocusCollaborationRoom | undefined\n const cleanups: (() => void)[] = []\n setReady(undefined)\n setError('')\n setStatus('Connecting\u2026')\n setDirty(false)\n dirtyRef.current = false\n // A refusal for another room format: \"Updating\u2026\" while the matching editor or server arrives.\n const updating = (reason: string | undefined): boolean => {\n const cancel = awaitMatchingEditor(reason, () => setRetry((x) => x + 1))\n if (!cancel) return false\n cleanups.push(cancel)\n setError('')\n setStatus('Updating\u2026')\n return true\n }\n async function start() {\n const fonts = await adapter.loadFonts()\n if (isDraft || snapshot) {\n const data = isDraft\n ? (!streamRef.current && drafts.get(documentId)) ||\n (draftContent === '' && adapter.houseTemplate\n ? await (async () => {\n // A blank note starts from the house template, as File \u203A New from it does.\n const template = await resolveHouseTemplate(adapter.houseTemplate)\n return newFromTemplate(template.bytes, {\n attachedTemplate: templateFileName(template),\n })\n })()\n : await (\n await adapter.request('/prepare', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content: draftContent }),\n })\n ).arrayBuffer())\n : await (await adapter.request(contentPath(documentId))).arrayBuffer()\n if (!cancelled) {\n setReady({\n document: new Uint8Array(data),\n fonts,\n modules: [reviewModule()],\n canEdit: !snapshot,\n author: adapter.author || 'You',\n filename: title,\n })\n setStatus(snapshot ? 'Saved version \u00B7 read only' : 'Unsaved note')\n }\n return\n }\n const session = await adapter.open(documentId)\n const ws = new URL(session.websocket_path, adapter.baseUrl || location.origin)\n ws.protocol = ws.protocol === 'https:' ? 'wss:' : 'ws:'\n let initial = true\n room = await createHocuspocusCollaboration({\n url: ws.toString(),\n roomId: session.room_id,\n identity: session.identity,\n offlineEditing: true,\n token: async () => {\n const next = initial ? session : await adapter.open(documentId)\n initial = false\n if (!cancelled)\n setReady((previous) => (previous ? { ...previous, canEdit: next.can_edit } : previous))\n return JSON.stringify({\n capability: next.token,\n versions: DOCUMENT_COLLABORATION_VERSIONS,\n })\n },\n })\n if (cancelled) {\n room.destroy()\n return\n }\n const current = room\n cleanups.push(\n current.session.subscribeStatus((s, _reason, detail) => {\n const disconnected = s === 'disconnected'\n setOffline(disconnected)\n if (s === 'error') {\n if (updating(detail)) return\n setError(\n detail ||\n 'The collaboration session failed. Export your local document before reconnecting.'\n )\n setStatus('Connection failed')\n } else if (disconnected) setStatus('Offline \u00B7 edits buffered locally')\n else if (s === 'ready') {\n setError('')\n setStatus(dirtyRef.current ? 'Saving changes\u2026' : 'Connected')\n }\n })\n )\n const stateless = ({ payload }: { payload: string }) => {\n try {\n const message = JSON.parse(payload) as {\n type: string\n message?: string\n hash?: string\n vector?: string\n receipt?: string\n }\n if (message.type === 'persisted') {\n if (\n !cancelled &&\n message.vector &&\n message.receipt &&\n covered(current, message.vector, message.receipt)\n ) {\n dirtyRef.current = false\n setDirty(false)\n setStatus('All changes saved')\n }\n }\n if (message.type === 'pending') setStatus('Saving changes\u2026')\n if (message.type === 'save-error') setStatus(message.message || 'Autosave failed')\n } catch {\n /* Ignore unrelated provider messages. */\n }\n }\n current.provider.on('stateless', stateless)\n cleanups.push(() => current.provider.off('stateless', stateless))\n if (adapter.subscribeTokenChanges)\n cleanups.push(\n adapter.subscribeTokenChanges(() => {\n void current.provider\n .sendToken()\n .catch(() => setStatus('Could not renew the collaboration session'))\n })\n )\n const refresh = setInterval(\n () => {\n void current.provider\n .sendToken()\n .catch(() => setStatus('Could not renew the collaboration session'))\n },\n 5 * 60 * 1000\n )\n cleanups.push(() => clearInterval(refresh))\n setReady({\n document: current.document,\n fonts,\n modules: [reviewModule(), collaborationModule({ session: current.session })],\n room: current,\n canEdit: session.can_edit,\n author: session.identity.name,\n filename: session.filename,\n })\n setStatus(session.can_edit ? 'All changes saved' : 'Read only \u00B7 live')\n }\n void start().catch((e) => {\n const message = e instanceof Error ? e.message : String(e)\n if (!cancelled && !updating(message)) setError(message)\n })\n return () => {\n cancelled = true\n cleanups.forEach((f) => f())\n clearTimeout(draftTimer.current)\n fitCleanup.current?.()\n room?.destroy()\n }\n }, [documentId, isDraft, snapshot, retry]) // draftContent seeds once, never remount on typing.\n useEffect(() => {\n if (!stateRef) return\n const room = ready?.room\n stateRef.current = () => (room ? encodeState(room) : undefined)\n return () => {\n stateRef.current = null\n }\n }, [stateRef, ready?.room])\n useEffect(() => {\n adapter.onDirtyChange?.(dirty)\n const beforeUnload = (e: BeforeUnloadEvent) => {\n if (dirtyRef.current) e.preventDefault()\n }\n window.addEventListener('beforeunload', beforeUnload)\n return () => {\n window.removeEventListener('beforeunload', beforeUnload)\n adapter.onDirtyChange?.(false)\n }\n }, [dirty])\n async function exportDocument() {\n runBeforeSave(ref.current)\n const data = await ref.current?.save()\n if (!data) return\n const url = URL.createObjectURL(\n new Blob([normalizeDocxExport(data)], {\n type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n })\n )\n const a = document.createElement('a')\n a.href = url\n a.download = title.replace(/\\.[^.]+$/, '') + '.docx'\n a.click()\n setTimeout(() => URL.revokeObjectURL(url), 5000)\n }\n useLayoutEffect(() => {\n const editor = ref.current\n return () => {\n if (isDraft && editor && dirtyRef.current)\n void editor\n .save()\n .then((bytes) => {\n if (bytes) drafts.set(documentId, bytes)\n })\n .catch(() => {})\n }\n }, [documentId, isDraft, ready])\n async function saveVersion() {\n if (!ready || saving || stream) return\n setSaving(true)\n runBeforeSave(ref.current)\n const atRevision = revision.current\n try {\n const result = isDraft\n ? await (async () => {\n const bytes = await ref.current?.save()\n if (!bytes) throw new Error('The editor is not ready.')\n return (\n await adapter.request(`/notes?${new URLSearchParams({ title })}`, {\n method: 'POST',\n headers: {\n 'Content-Type':\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n },\n body: bytes,\n })\n ).json() as Promise<{ document_ext_id: string }>\n })()\n : await adapter.save(documentId, ready.room ? encodeState(ready.room) : undefined)\n if (revision.current === atRevision) {\n dirtyRef.current = false\n setDirty(false)\n drafts.delete(documentId)\n }\n await Promise.resolve(adapter.onVersionSaved?.(result.document_ext_id)).catch(() => {\n /* The saved document remains accessible by its ID. */\n })\n onSaved?.(result.document_ext_id)\n adapter.notify?.(isDraft ? 'Word note saved' : 'DOCX version saved', 'success')\n } catch (e) {\n adapter.notify?.(e instanceof Error ? e.message : 'Could not save this document.', 'error')\n setStatus('Save failed \u00B7 your draft is retained')\n } finally {\n setSaving(false)\n }\n }\n function editorReady(editor: Editor) {\n ref.current = editor\n if (streamRef.current) {\n streamWriter.current = new WordDraftStream(editor)\n updateStream()\n }\n fitCleanup.current?.()\n fitted.current = undefined\n const viewport = stageRef.current?.querySelector<HTMLElement>('.native-docx-viewport')\n if (!viewport) return\n let surface: Element | null = null\n const fit = () => {\n // The page itself: laid out after the editor is ready, and resized by every zoom.\n const page = viewport.querySelector('.docx-paginated-surface')\n if (page && page !== surface) resize.observe((surface = page))\n const current = editor.getZoom()\n // A zoom the fit did not apply is the reader's: stop fitting until they pick Fit width again.\n if (\n fitting.current &&\n fitted.current !== undefined &&\n Math.abs(current - fitted.current) > 0.001\n )\n fitting.current = false\n setFitWidth(fitting.current)\n setZoomPercent(Math.round(current * 100))\n if (!fitting.current) return\n const pageWidth = editor.getPageGeometry()[0]?.box.width\n if (!pageWidth) return\n const style = getComputedStyle(viewport)\n const available =\n viewport.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight)\n // The page fills the viewer, its padding the only gutter. Compact (an email body) never\n // magnifies: its text stays the size the email is read at.\n const zoom = Math.max(0.1, Math.min(compact ? 1 : 5, available / pageWidth))\n if (Math.abs(current - zoom) > 0.001) editor.setZoom(zoom)\n fitted.current = editor.getZoom()\n setZoomPercent(Math.round(fitted.current * 100))\n }\n refit.current = fit\n const resize = new ResizeObserver(fit)\n const chrome = new MutationObserver(fit)\n resize.observe(viewport)\n chrome.observe(viewport, {\n attributes: true,\n attributeFilter: ['style', 'data-review-pane', 'data-review-margin'],\n })\n // Where the page mounts, to start watching it if it is laid out after the editor is ready.\n const mount = viewport.querySelector('.docx-content-mount')\n if (mount) chrome.observe(mount, { childList: true })\n if (!fitting.current) editor.setZoom(zoomPercent / 100)\n fit()\n fitCleanup.current = () => {\n resize.disconnect()\n chrome.disconnect()\n refit.current = undefined\n }\n }\n function pickZoom(value: string) {\n const editor = ref.current\n if (!editor) return\n if (value === 'fit') {\n fitting.current = true\n fitted.current = undefined\n refit.current?.()\n return\n }\n fitting.current = false\n setFitWidth(false)\n setZoomPercent(Number(value))\n editor.setZoom(Number(value) / 100)\n }\n function changed() {\n if (snapshot) return\n revision.current += 1\n dirtyRef.current = true\n setDirty(true)\n setStatus(\n isDraft ? 'Unsaved note' : offline ? 'Offline \u00B7 edits buffered locally' : 'Saving changes\u2026'\n )\n if (isDraft) {\n clearTimeout(draftTimer.current)\n draftTimer.current = setTimeout(() => {\n void ref.current?.save().then((bytes) => {\n if (bytes) drafts.set(documentId, bytes)\n })\n }, 200)\n }\n }\n return (\n <section\n className={compact ? 'native-docx-viewer native-docx-compact' : 'native-docx-viewer'}\n data-testid=\"native-docx-editor\"\n aria-busy={!!stream?.busy}\n data-generation-state={\n stream ? (stream.busy ? 'generating' : stream.error ? 'stopped' : 'generated') : 'ready'\n }\n >\n {offline && (\n <div className=\"native-docx-notice\">\n Changes are buffered in this browser. Keep this tab open until the connection returns, or\n download your DOCX.\n </div>\n )}\n {error && (\n <div className=\"native-docx-notice\" data-error=\"true\" role=\"alert\">\n {error}{' '}\n <button\n disabled={!stream && dirty}\n title={dirty ? 'Download your unsaved DOCX before reopening the editor' : undefined}\n onClick={() =>\n stream ? (setError(''), setStreamAttempt((x) => x + 1)) : setRetry((x) => x + 1)\n }\n >\n <RefreshCw size={12} />\n Retry\n </button>\n </div>\n )}\n {!ready && !error && (\n <div className=\"native-docx-error\" role=\"status\">\n Opening Word document\u2026\n </div>\n )}\n {ready && (\n <div className=\"native-docx-body docx-editor\">\n <EditorBoundary key={retry}>\n <DocxEditor.Root\n document={ready.document}\n modules={ready.modules}\n fonts={ready.fonts}\n mode={\n stream || (isDraft && ready.canEdit && !snapshot) || (compact && ready.canEdit)\n ? 'edit'\n : !ready.canEdit || snapshot\n ? 'view'\n : 'suggesting'\n }\n reviewDisplayMode=\"all-markup\"\n zoomMode={fixedZoomMode}\n author={ready.author}\n onReady={editorReady}\n onChange={(change) => {\n if (change.source !== 'load') changed()\n }}\n onFontError={(e) => setError(e.message)}\n >\n <DocxAuthorContext.Provider value={ready.author}>\n <DefinedTermsProvider\n load={adapter.definitions}\n editable={!stream && !snapshot && ready.canEdit}\n notify={adapter.notify}\n >\n <HouseTemplateProvider\n enabled={!stream}\n host={adapter.houseTemplate}\n documentId={isDraft || snapshot ? undefined : documentId}\n editable={!stream && !snapshot && ready.canEdit}\n notify={adapter.notify}\n >\n <CrossReferencesProvider\n editable={!stream && !snapshot && ready.canEdit}\n references={adapter.references}\n documentId={documentId}\n notify={adapter.notify}\n >\n <SignatureFieldsProvider\n signers={adapter.signatureSigners}\n mySignature={adapter.savedSignature}\n editable={!stream && !snapshot && ready.canEdit}\n notify={adapter.notify}\n >\n <DocxEditor.RevisionMarkup\n insertions={{ mark: 'underline', color: 'blue' }}\n deletions={{ mark: 'strikethrough', color: 'red' }}\n movedFrom={{ mark: 'doubleStrikethrough', color: 'green' }}\n movedTo={{ mark: 'doubleUnderline', color: 'green' }}\n trackMoves\n />\n {compact && !stream && <CompactToolbar />}\n {!compact && !stream && (\n <DocxRibbon\n onSave={() => void saveVersion()}\n imageGeneration={\n adapter.imageGeneration && {\n notify: adapter.notify,\n ...adapter.imageGeneration,\n }\n }\n badge={\n // The document's state, in place of a title row above the ribbon.\n <DocumentStateBadge\n state={\n snapshot || !ready.canEdit\n ? 'read-only'\n : ready.room\n ? 'co-editing'\n : isDraft\n ? 'draft'\n : undefined\n }\n />\n }\n />\n )}\n {!stream && <WordShortcuts scope={stageRef} />}\n {!stream && <TableTabKeys scope={stageRef} />}\n <div\n className=\"native-docx-stage\"\n ref={stageRef}\n onMouseDownCapture={(event) => {\n if (event.button === 2 && ref.current?.getSelectionPlacement())\n event.preventDefault()\n }}\n >\n <DocxEditor.Viewport className=\"native-docx-viewport\">\n <DocxEditor.Content />\n <DocxMentions\n initialCommentId={initialCommentId}\n mentions={adapter.mentions}\n notify={adapter.notify}\n getAgentStatus={adapter.getAgentStatus}\n requestAgent={\n adapter.requestAgent\n ? (request) => adapter.requestAgent!(documentId, request)\n : undefined\n }\n >\n <RoomInputBinding session={ready.room?.session} />\n <AgentUndoRoom.Provider value={ready.room?.ydoc ?? null}>\n <DocxEditorReview>\n {() => (\n <DocxEditorReview.Card>\n <DocxCommentActivity />\n <AgentUndo />\n </DocxEditorReview.Card>\n )}\n </DocxEditorReview>\n </AgentUndoRoom.Provider>\n </DocxMentions>\n {!compact && <DocxEditor.HeaderFooterChrome />}\n {!compact && <DocxEditor.NotesChrome />}\n <DocxEditor.Equation />\n <DocxEditor.HyperLink />\n <DocxEditor.ContextMenu>\n <DocxContextMenuExtras />\n <MySignatureContextItems />\n </DocxEditor.ContextMenu>\n </DocxEditor.Viewport>\n {!compact && <DocxEditor.PageNumber />}\n </div>\n </SignatureFieldsProvider>\n </CrossReferencesProvider>\n </HouseTemplateProvider>\n </DefinedTermsProvider>\n </DocxAuthorContext.Provider>\n </DocxEditor.Root>\n </EditorBoundary>\n </div>\n )}\n <div className=\"native-docx-actions\">\n <span className=\"native-docx-status\" role=\"status\">\n {offline ? <WifiOff size={14} /> : !dirty && ready ? <Check size={14} /> : null}\n {status}\n </span>\n <DocxParticipants session={ready?.room?.session} />\n {!compact && (\n <select\n className=\"native-docx-zoom\"\n aria-label=\"Zoom\"\n data-testid=\"native-docx-zoom\"\n disabled={!ready}\n value={fitWidth ? 'fit' : String(zoomPercent)}\n onChange={(event) => pickZoom(event.target.value)}\n >\n <option value=\"fit\">Fit width</option>\n {[...new Set([...ZOOM_LEVELS, ...(fitWidth ? [] : [zoomPercent])])]\n .sort((a, b) => a - b)\n .map((level) => (\n <option key={level} value={String(level)}>\n {level}%\n </option>\n ))}\n </select>\n )}\n {!compact && (\n <button\n onClick={() => void exportDocument()}\n disabled={!ready}\n aria-label=\"Download DOCX\"\n >\n <Download size={14} />\n DOCX\n </button>\n )}\n {!compact && !snapshot && !stream && ready?.canEdit && (\n <button\n className=\"native-docx-save\"\n onClick={() => void saveVersion()}\n disabled={!ready || saving || offline}\n data-testid=\"native-docx-save\"\n >\n <Save size={14} />\n {saving ? 'Saving\u2026' : isDraft ? 'Save note' : 'Save version'}\n </button>\n )}\n </div>\n </section>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { normalizeDocxExport } from './export'\nimport { WordDraftStream } from './streamWordDocument'\nimport {\n DocxMentions,\n DocxCommentActivity,\n type DocxMention,\n type DocxAgentCommentRequest,\n type DocxMentionDelivery,\n type DocxAgentRunStatus,\n} from './DocxMentions'\nimport * as Y from 'yjs'\nimport type { DocumentHandle } from '@docx-editor.dev/core'\nimport React, { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport {\n DocxEditor,\n useChromeTranslate,\n useDocxEditor,\n type FontConfiguration,\n} from '@docx-editor.dev/react'\nimport { collaborationModule, DOCUMENT_COLLABORATION_VERSIONS } from '@arbidocs/coedit'\nimport { awaitMatchingEditor } from './coedit-update'\nimport type { DocxCollaborationSession } from '@arbidocs/coedit'\nimport {\n createHocuspocusCollaboration,\n type HocuspocusCollaborationRoom,\n} from '@arbidocs/coedit/hocuspocus'\nimport { DocxEditorReview, reviewModule } from './review'\nimport { AgentUndo, AgentUndoRoom } from './AgentUndo'\nimport type { EditorModule } from '@docx-editor.dev/core'\nimport type { Editor } from '@docx-editor.dev/core'\nimport {\n Download,\n Save,\n RefreshCw,\n WifiOff,\n Check,\n Type,\n Pilcrow,\n UsersRound,\n BookA,\n} from 'lucide-react'\nimport { DefinedTermsProvider, useDefinedTerms } from './definitions/DefinedTerms'\nimport { RibbonMenu } from './RibbonMenu'\nimport { DocxCommandMenu } from './DocxCommandMenu'\nimport { RibbonItem, RibbonOverflow } from './RibbonOverflow'\nimport { StyleGallery } from './StyleGallery'\nimport { NoteButtons, WordShortcuts } from './WordReferences'\nimport type { DefinitionSource } from '../tags/definitions'\nimport { CrossReferencesProvider, type DocxReferencesAdapter } from './references/CrossReferences'\nimport {\n CrossReferenceButton,\n DocxContextMenuExtras,\n UpdateCrossReferencesButton,\n} from './references/EditorMenus'\nimport { runBeforeSave } from './beforeSave'\nimport { LayoutTabContent, LAYOUT_TAB, useContextualTabs } from './layout/LayoutTabs'\nimport {\n GenerateImageButton,\n useGenerateImageTarget,\n type DocxImageGeneration,\n} from './layout/GenerateImage'\nimport { TableTabKeys } from './layout/TableKeys'\nimport { newFromTemplate } from '@arbidocs/coedit/template'\nimport {\n HouseTemplateProvider,\n resolveHouseTemplate,\n templateFileName,\n type HouseTemplateHost,\n} from './template/HouseTemplate'\nimport { QuickParts } from './template/QuickParts'\nimport {\n MySignatureContextItems,\n SignatureFieldContextItem,\n MySignatureMenu,\n SignatureFieldMenu,\n SignatureFieldsProvider,\n type DocxSavedSignature,\n type DocxSigner,\n} from './signatures/SignatureFields'\nimport { HouseTemplatePanel } from './template/HouseTemplatePanel'\nimport { DocxAuthorContext } from './structural/useTrackedOrNoted'\n\nimport { contentPath } from './content-path'\n\nexport { contentPath }\n\n/** Host integration: no application store, router, or authentication singleton is required. */\nexport interface NativeDocxAdapter {\n request: (path: string, options?: RequestInit) => Promise<Response>\n open: (documentId: string) => Promise<{\n room_id: string\n token: string\n websocket_path: string\n can_edit: boolean\n identity: { actorId: string; name: string; role: 'human' | 'agent' }\n filename: string\n }>\n /** Save the live room as the document's next version (same document id). */\n save: (\n documentId: string,\n state?: string\n ) => Promise<{ document_ext_id: string; version?: number; unchanged?: boolean }>\n loadFonts: () => Promise<FontConfiguration>\n baseUrl?: string\n author?: string\n subscribeTokenChanges?: (listener: () => void) => () => void\n onDirtyChange?: (dirty: boolean) => void\n onVersionSaved?: (documentId: string, version?: number) => void | Promise<void>\n notify?: (message: string, kind: 'success' | 'error') => void\n mentions?: readonly DocxMention[]\n requestAgent?: (\n documentId: string,\n request: DocxAgentCommentRequest\n ) => Promise<DocxMentionDelivery | void>\n getAgentStatus?: (responseId: string) => Promise<DocxAgentRunStatus>\n /**\n * The workspace's definitions: facts labelled \"Definitions\". Present: the Insert tab offers\n * Defined term, and typing `@@` in the body opens the term type-ahead.\n */\n definitions?: () => Promise<DefinitionSource[]>\n /**\n * References to the workspace's other documents. Present: Insert cross-reference also offers a\n * passage of another document, inserted as a link that opens it there.\n */\n references?: DocxReferencesAdapter\n /** The platform's image generation. Present: the Insert tab offers Generate image. */\n imageGeneration?: DocxImageGeneration\n /**\n * The workspace's house template. Present: a blank note starts from it (its styles, numbering,\n * page setup, headers and footers), Insert offers its Quick Parts, and the Design tab and the\n * style box show where the document's styles differ from it.\n */\n houseTemplate?: HouseTemplateHost\n /** Workspace members who may sign. Present: Insert offers Signature field (or anyone by email). */\n signatureSigners?: readonly DocxSigner[]\n /** One's saved signature. Present: Insert offers My signature (an informal one, as a picture). */\n savedSignature?: DocxSavedSignature\n}\n\nexport interface NativeDocxEditorProps {\n adapter: NativeDocxAdapter\n documentId: string\n title: string\n draftContent?: string\n initialCommentId?: string\n /** Immutable history/compare snapshots must not join the live editing room. */\n snapshot?: boolean\n onSaved?: (id: string) => void\n /**\n * Read-only preview of generated Markdown. The server stores the DOCX itself; when the\n * stream ends the caller swaps this preview for the stored document.\n */\n stream?: {\n content: string\n busy: boolean\n error?: string | null\n }\n /**\n * Embedded as a body field (an email draft): a small formatting toolbar instead of the ribbon, no\n * page furniture or save bar (the host saves), and the person types directly; others' edits (ARBI's)\n * still arrive as tracked changes to accept or reject.\n */\n compact?: boolean\n /** Receives a reader of the live room's state, so the host's save can include the latest keystrokes. */\n stateRef?: React.MutableRefObject<(() => string | undefined) | null>\n /** Save the current live room before leaving the editor; false means the caller must stay. */\n saveRef?: React.MutableRefObject<(() => Promise<boolean | number>) | null>\n}\ninterface Ready {\n document: DocumentHandle | Uint8Array\n modules: readonly EditorModule[]\n fonts: FontConfiguration\n room?: HocuspocusCollaborationRoom\n canEdit: boolean\n author: string\n filename: string\n}\n// Local unsaved notes survive tab switches. Persisted artifacts use server state.\nconst drafts = new Map<string, ArrayBuffer>()\nconst stateBytes = (room: HocuspocusCollaborationRoom) => Y.encodeStateAsUpdate(room.ydoc)\nconst encodeState = (room: HocuspocusCollaborationRoom) => {\n let binary = ''\n for (const byte of stateBytes(room)) binary += String.fromCharCode(byte)\n return btoa(binary)\n}\nfunction covered(room: HocuspocusCollaborationRoom, vector: string, receipt: string) {\n const decode = (value: string) => Uint8Array.from(atob(value), (c) => c.charCodeAt(0))\n const server = Y.decodeStateVector(decode(vector)),\n local = Y.decodeStateVector(Y.encodeStateVector(room.ydoc))\n for (const [client, clock] of local) if ((server.get(client) || 0) < clock) return false\n const deleted = Y.decodeUpdate(stateBytes(room)).ds.clients\n const saved = Y.decodeUpdate(decode(receipt)).ds.clients\n for (const [client, ranges] of deleted)\n for (const range of ranges) {\n if (\n !(saved.get(client) || []).some(\n (s) => s.clock <= range.clock && s.clock + s.len >= range.clock + range.len\n )\n )\n return false\n }\n return true\n}\nclass EditorBoundary extends React.Component<{ children: React.ReactNode }, { error?: Error }> {\n state: { error?: Error } = {}\n static getDerivedStateFromError(error: Error) {\n return { error }\n }\n render() {\n return this.state.error ? (\n <div role=\"alert\" className=\"native-docx-error\">\n Could not render this Word document: {this.state.error.message}\n </div>\n ) : (\n this.props.children\n )\n }\n}\n/**\n * The room writes below the editor's input buffer, so it gets the editor's pending-input flush: it\n * lands queued typing before a peer's change and lays that change out at once, which is when the\n * editor carries its caret (otherwise a fast keystroke lands where the caret was before the change).\n */\nfunction RoomInputBinding({\n session,\n flushRef,\n}: {\n session?: DocxCollaborationSession\n flushRef: React.MutableRefObject<(() => void) | null>\n}) {\n const editor = useDocxEditor()\n useEffect(() => {\n if (!editor) return\n const flush = () => editor.surface?.flushPendingInput()\n flushRef.current = flush\n const unbind = session?.bindEditorInput(flush)\n return () => {\n if (flushRef.current === flush) flushRef.current = null\n unbind?.()\n }\n }, [editor, session, flushRef])\n return null\n}\n\nexport function DocxParticipants({ session }: { session?: DocxCollaborationSession }) {\n const [people, setPeople] = useState<readonly { actorId: string; name: string }[]>([])\n useEffect(() => {\n if (!session) return\n setPeople(session.participants())\n return session.subscribeParticipants(setPeople)\n }, [session])\n return (\n <div className=\"native-docx-presence\" aria-label=\"People viewing this document\">\n {people.map((p) => (\n <span className=\"native-docx-avatar\" key={p.actorId} title={p.name}>\n {p.name\n .split(' ')\n .map((s) => s[0])\n .slice(0, 2)\n .join('')}\n </span>\n ))}\n </div>\n )\n}\n\n/** Insert tab: a defined term at the caret (when definitions are offered). */\nfunction DefinedTermButtons() {\n const terms = useDefinedTerms()\n if (!terms) return null\n return (\n <button\n type=\"button\"\n className=\"native-docx-ribbon-trigger\"\n aria-label={terms.labels.insert}\n title={`${terms.labels.insert} (type @@)`}\n data-testid=\"docx-insert-defined-term\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => terms.openPicker(event.currentTarget)}\n >\n <BookA size={16} />\n </button>\n )\n}\n\nconst DOCUMENT_STATES = {\n 'co-editing': {\n label: 'Co-editing',\n title: 'Edits sync live with everyone who has this document open',\n },\n 'read-only': {\n label: 'Read-only',\n title: 'This copy cannot be edited: an earlier version, or the last saved copy',\n },\n draft: { label: 'Private draft', title: 'Only you can see this until you save it' },\n} as const\n\n/** Which document is on screen: shared live, read-only, or a draft only its author sees. */\nfunction DocumentStateBadge({ state }: { state?: keyof typeof DOCUMENT_STATES }) {\n if (!state) return null\n const { label, title } = DOCUMENT_STATES[state]\n return (\n <span data-state={state} title={title}>\n {label}\n </span>\n )\n}\n\nexport function DocxRibbon({\n onSave,\n badge,\n imageGeneration,\n}: {\n onSave: () => void\n /** Insert \u203A Generate image, when the host can generate images. */\n imageGeneration?: DocxImageGeneration\n /** A short state label at the end of the row, such as \"Co-editing\". */\n badge?: React.ReactNode\n}) {\n const [selected, setTab] = useState('Home')\n const contextual = useContextualTabs(selected)\n useGenerateImageTarget()\n const tab = contextual.shown\n const t = useChromeTranslate()\n return (\n <div className=\"native-docx-ribbon\">\n <select aria-label=\"Ribbon tab\" value={tab} onChange={(event) => setTab(event.target.value)}>\n <option>Home</option>\n <option>Insert</option>\n <option>Design</option>\n <option>{LAYOUT_TAB}</option>\n <option>References</option>\n <option>Review</option>\n {contextual.tabs.map((name) => (\n <option key={name}>{name}</option>\n ))}\n </select>\n <DocxEditor.Toolbar t={t} preset={false} onSave={onSave}>\n <DocxEditor.Toolbar.Undo />\n <DocxEditor.Toolbar.Redo />\n <DocxEditor.Toolbar.Save />\n {/* Undo, Redo and Save stay put, like Word's Quick Access Toolbar; the tab's own\n controls collapse into its More menu when the ribbon is too narrow for them. */}\n <RibbonOverflow tab={tab}>\n {tab === 'Home' && (\n <>\n <RibbonItem id=\"home-style\" label=\"Styles\" priority={80}>\n <StyleGallery />\n </RibbonItem>\n <RibbonItem id=\"home-bold\" label=\"Bold\" priority={100}>\n <DocxEditor.Toolbar.Bold />\n </RibbonItem>\n <RibbonItem id=\"home-italic\" label=\"Italic\" priority={95}>\n <DocxEditor.Toolbar.Italic />\n </RibbonItem>\n <RibbonItem id=\"home-underline\" label=\"Underline\" priority={90}>\n <DocxEditor.Toolbar.Underline />\n </RibbonItem>\n <RibbonItem id=\"home-font\" label=\"Font\" priority={60}>\n <RibbonMenu label=\"Font\" icon={<Type size={16} />}>\n <DocxEditor.Toolbar.FontFamily />\n <DocxEditor.Toolbar.FontSize />\n <DocxEditor.Toolbar.FontColor />\n <DocxEditor.Toolbar.Highlight />\n </RibbonMenu>\n </RibbonItem>\n <RibbonItem id=\"home-more-formatting\" label=\"More formatting\" priority={50}>\n <RibbonMenu label=\"More formatting\" icon={<Pilcrow size={16} />}>\n <DocxEditor.Toolbar.Alignment />\n <DocxEditor.Toolbar.BulletList />\n <DocxEditor.Toolbar.NumberedList />\n <DocxEditor.Toolbar.LineSpacing />\n <DocxEditor.Toolbar.Indent />\n <DocxEditor.Toolbar.Outdent />\n <DocxEditor.Toolbar.Strike />\n <DocxEditor.Toolbar.ClearFormatting />\n </RibbonMenu>\n </RibbonItem>\n </>\n )}\n {tab === 'Insert' && (\n <>\n <RibbonItem id=\"insert-table\" label=\"Table\">\n <DocxEditor.Toolbar.TableInsert />\n </RibbonItem>\n <RibbonItem id=\"insert-picture\" label=\"Picture\">\n <DocxEditor.Toolbar.ImageInsert />\n </RibbonItem>\n {imageGeneration && (\n <RibbonItem id=\"insert-generate-image\" label=\"Generate image\">\n <GenerateImageButton generation={imageGeneration} />\n </RibbonItem>\n )}\n <RibbonItem id=\"insert-page-break\" label=\"Page break\">\n <DocxEditor.Toolbar.Button slotId=\"insert.pageBreak\" />\n </RibbonItem>\n <RibbonItem id=\"insert-link\" label=\"Link\">\n <DocxEditor.Toolbar.Link />\n </RibbonItem>\n <RibbonItem id=\"insert-defined-term\" label=\"Defined term\">\n <DefinedTermButtons />\n </RibbonItem>\n <RibbonItem id=\"insert-quick-parts\" label=\"Quick Parts\">\n <QuickParts />\n </RibbonItem>\n <RibbonItem id=\"insert-signature-field\" label=\"Signature field\">\n <SignatureFieldMenu />\n </RibbonItem>\n <RibbonItem id=\"insert-my-signature\" label=\"My signature\">\n <MySignatureMenu />\n </RibbonItem>\n <RibbonItem id=\"insert-cross-reference\" label=\"Cross-reference\">\n <CrossReferenceButton />\n </RibbonItem>\n </>\n )}\n <LayoutTabContent tab={tab} />\n {tab === 'Design' && (\n <RibbonItem id=\"design-house-template\" label=\"House template\">\n <HouseTemplatePanel />\n </RibbonItem>\n )}\n {tab === 'References' && (\n <>\n <NoteButtons />\n <RibbonItem id=\"references-cross-reference\" label=\"Cross-reference\">\n <CrossReferenceButton />\n </RibbonItem>\n <RibbonItem id=\"references-update-cross-references\" label=\"Update cross-references\">\n <UpdateCrossReferencesButton />\n </RibbonItem>\n </>\n )}\n {tab === 'Review' && (\n <>\n <RibbonItem id=\"review-editing-mode\" label=\"Editing mode\" priority={10}>\n <DocxEditor.Toolbar.EditingMode />\n </RibbonItem>\n <RibbonItem id=\"review-comments\" label=\"Comments\">\n <DocxEditor.Toolbar.Comments />\n </RibbonItem>\n <RibbonItem id=\"review-options\" label=\"Review options\">\n <RibbonMenu label=\"Review options\" icon={<UsersRound size={16} />}>\n <DocxEditor.Toolbar.Reviewers />\n </RibbonMenu>\n </RibbonItem>\n </>\n )}\n </RibbonOverflow>\n {/* The toolbar provides its table chrome context only to a direct table-chrome child: this\n hidden one keeps it mounted for the Table tab's borders and shading. */}\n <DocxEditor.Toolbar.TableCellFill hidden />\n </DocxEditor.Toolbar>\n {badge && (\n <span className=\"native-docx-ribbon-badge\" data-testid=\"docx-ribbon-badge\">\n {badge}\n </span>\n )}\n </div>\n )\n}\n\n/** The compact editor's formatting: what an email needs. */\nfunction CompactToolbar() {\n const t = useChromeTranslate()\n return (\n <DocxEditor.Toolbar t={t} preset={false}>\n <DocxEditor.Toolbar.Undo />\n <DocxEditor.Toolbar.Redo />\n <DocxEditor.Toolbar.Bold />\n <DocxEditor.Toolbar.Italic />\n <DocxEditor.Toolbar.Underline />\n <DocxEditor.Toolbar.BulletList />\n <DocxEditor.Toolbar.NumberedList />\n <DocxEditor.Toolbar.Link />\n </DocxEditor.Toolbar>\n )\n}\n\nconst fixedZoomMode = { type: 'fixed' } as const\n/** The zoom menu's levels, in percent, beside Fit width. */\nconst ZOOM_LEVELS = [50, 75, 100, 125, 150, 200]\n\nexport function NativeDocxEditor({\n documentId,\n title,\n draftContent,\n initialCommentId,\n snapshot = false,\n onSaved,\n stream,\n adapter,\n compact = false,\n stateRef,\n saveRef,\n}: NativeDocxEditorProps) {\n const [ready, setReady] = useState<Ready>(),\n [error, setError] = useState(''),\n [retry, setRetry] = useState(0)\n const [status, setStatus] = useState('Connecting\u2026'),\n [dirty, setDirty] = useState(false),\n [saving, setSaving] = useState(false),\n [offline, setOffline] = useState(false)\n const revision = useRef(0)\n const savingRef = useRef(false)\n const flushInputRef = useRef<(() => void) | null>(null)\n const stageRef = useRef<HTMLDivElement>(null),\n fitCleanup = useRef<(() => void) | undefined>(undefined),\n refit = useRef<(() => void) | undefined>(undefined)\n // Fit width until the reader picks a zoom (the zoom menu, or Ctrl +/-/0), then keep theirs until\n // they pick Fit width again. `fitted` is the zoom the fit last applied: any other zoom is theirs.\n const fitting = useRef(true),\n fitted = useRef<number | undefined>(undefined)\n const [fitWidth, setFitWidth] = useState(true),\n [zoomPercent, setZoomPercent] = useState(100)\n const ref = useRef<Editor | null>(null),\n dirtyRef = useRef(false),\n draftTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const isDraft = draftContent !== undefined\n const streamRef = useRef(stream)\n streamRef.current = stream\n const streamWriter = useRef<WordDraftStream | null>(null)\n const streamFinished = useRef(false)\n const streamTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const [streamAttempt, setStreamAttempt] = useState(0)\n function updateStream() {\n const current = streamRef.current\n if (!current || !streamWriter.current || streamFinished.current) return\n try {\n streamWriter.current.update(current.content, !current.busy)\n setStatus(\n current.busy\n ? 'Generating \u00B7 editing is locked'\n : current.error\n ? 'Generation stopped \u00B7 draft retained'\n : 'Opening the saved document\u2026'\n )\n if (!current.busy && !current.error) streamFinished.current = true\n } catch (failure) {\n setError(\n failure instanceof Error ? failure.message : 'Could not import the generated document.'\n )\n }\n }\n useEffect(() => {\n if (!streamRef.current) return\n if (!streamRef.current.busy) {\n clearTimeout(streamTimer.current)\n streamTimer.current = undefined\n updateStream()\n } else if (!streamTimer.current) {\n streamTimer.current = setTimeout(() => {\n streamTimer.current = undefined\n updateStream()\n }, 120)\n }\n }, [stream?.content, stream?.busy, stream?.error, streamAttempt])\n useEffect(() => () => clearTimeout(streamTimer.current), [])\n useEffect(() => {\n let cancelled = false\n let room: HocuspocusCollaborationRoom | undefined\n const cleanups: (() => void)[] = []\n setReady(undefined)\n setError('')\n setStatus('Connecting\u2026')\n setDirty(false)\n dirtyRef.current = false\n // A refusal for another room format: \"Updating\u2026\" while the matching editor or server arrives.\n const updating = (reason: string | undefined): boolean => {\n const cancel = awaitMatchingEditor(reason, () => setRetry((x) => x + 1))\n if (!cancel) return false\n cleanups.push(cancel)\n setError('')\n setStatus('Updating\u2026')\n return true\n }\n async function start() {\n const fonts = await adapter.loadFonts()\n if (isDraft || snapshot) {\n const data = isDraft\n ? (!streamRef.current && drafts.get(documentId)) ||\n (draftContent === '' && adapter.houseTemplate\n ? await (async () => {\n // A blank note starts from the house template, as File \u203A New from it does.\n const template = await resolveHouseTemplate(adapter.houseTemplate)\n return newFromTemplate(template.bytes, {\n attachedTemplate: templateFileName(template),\n })\n })()\n : await (\n await adapter.request('/prepare', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content: draftContent }),\n })\n ).arrayBuffer())\n : await (await adapter.request(contentPath(documentId))).arrayBuffer()\n if (!cancelled) {\n setReady({\n document: new Uint8Array(data),\n fonts,\n modules: [reviewModule()],\n canEdit: !snapshot,\n author: adapter.author || 'You',\n filename: title,\n })\n setStatus(snapshot ? 'Saved version \u00B7 read only' : 'Unsaved note')\n }\n return\n }\n const session = await adapter.open(documentId)\n const ws = new URL(session.websocket_path, adapter.baseUrl || location.origin)\n ws.protocol = ws.protocol === 'https:' ? 'wss:' : 'ws:'\n let initial = true\n room = await createHocuspocusCollaboration({\n url: ws.toString(),\n roomId: session.room_id,\n identity: session.identity,\n offlineEditing: true,\n token: async () => {\n const next = initial ? session : await adapter.open(documentId)\n initial = false\n if (!cancelled)\n setReady((previous) => (previous ? { ...previous, canEdit: next.can_edit } : previous))\n return JSON.stringify({\n capability: next.token,\n versions: DOCUMENT_COLLABORATION_VERSIONS,\n })\n },\n })\n if (cancelled) {\n room.destroy()\n return\n }\n const current = room\n cleanups.push(\n current.session.subscribeStatus((s, _reason, detail) => {\n const disconnected = s === 'disconnected'\n setOffline(disconnected)\n if (s === 'error') {\n if (updating(detail)) return\n setError(\n detail ||\n 'The collaboration session failed. Export your local document before reconnecting.'\n )\n setStatus('Connection failed')\n } else if (disconnected) setStatus('Offline \u00B7 edits buffered locally')\n else if (s === 'ready') {\n setError('')\n setStatus(dirtyRef.current ? 'Saving changes\u2026' : 'Connected')\n }\n })\n )\n const stateless = ({ payload }: { payload: string }) => {\n try {\n const message = JSON.parse(payload) as {\n type: string\n message?: string\n hash?: string\n vector?: string\n receipt?: string\n }\n if (message.type === 'persisted') {\n if (\n !cancelled &&\n message.vector &&\n message.receipt &&\n covered(current, message.vector, message.receipt)\n ) {\n dirtyRef.current = false\n setDirty(false)\n setStatus('All changes saved')\n }\n }\n if (message.type === 'pending') setStatus('Saving changes\u2026')\n if (message.type === 'save-error') setStatus(message.message || 'Autosave failed')\n } catch {\n /* Ignore unrelated provider messages. */\n }\n }\n current.provider.on('stateless', stateless)\n cleanups.push(() => current.provider.off('stateless', stateless))\n if (adapter.subscribeTokenChanges)\n cleanups.push(\n adapter.subscribeTokenChanges(() => {\n void current.provider\n .sendToken()\n .catch(() => setStatus('Could not renew the collaboration session'))\n })\n )\n const refresh = setInterval(\n () => {\n void current.provider\n .sendToken()\n .catch(() => setStatus('Could not renew the collaboration session'))\n },\n 5 * 60 * 1000\n )\n cleanups.push(() => clearInterval(refresh))\n setReady({\n document: current.document,\n fonts,\n modules: [reviewModule(), collaborationModule({ session: current.session })],\n room: current,\n canEdit: session.can_edit,\n author: session.identity.name,\n filename: session.filename,\n })\n setStatus(session.can_edit ? 'All changes saved' : 'Read only \u00B7 live')\n }\n void start().catch((e) => {\n const message = e instanceof Error ? e.message : String(e)\n if (!cancelled && !updating(message)) setError(message)\n })\n return () => {\n cancelled = true\n cleanups.forEach((f) => f())\n clearTimeout(draftTimer.current)\n fitCleanup.current?.()\n room?.destroy()\n }\n }, [documentId, isDraft, snapshot, retry]) // draftContent seeds once, never remount on typing.\n useEffect(() => {\n if (!stateRef) return\n const room = ready?.room\n stateRef.current = () => (room ? encodeState(room) : undefined)\n return () => {\n stateRef.current = null\n }\n }, [stateRef, ready?.room])\n useEffect(() => {\n adapter.onDirtyChange?.(dirty)\n const beforeUnload = (e: BeforeUnloadEvent) => {\n if (dirtyRef.current) e.preventDefault()\n }\n window.addEventListener('beforeunload', beforeUnload)\n return () => {\n window.removeEventListener('beforeunload', beforeUnload)\n adapter.onDirtyChange?.(false)\n }\n }, [dirty])\n async function exportDocument() {\n runBeforeSave(ref.current)\n const data = await ref.current?.save()\n if (!data) return\n const url = URL.createObjectURL(\n new Blob([normalizeDocxExport(data)], {\n type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n })\n )\n const a = document.createElement('a')\n a.href = url\n a.download = title.replace(/\\.[^.]+$/, '') + '.docx'\n a.click()\n setTimeout(() => URL.revokeObjectURL(url), 5000)\n }\n useLayoutEffect(() => {\n const editor = ref.current\n return () => {\n if (isDraft && editor && dirtyRef.current)\n void editor\n .save()\n .then((bytes) => {\n if (bytes) drafts.set(documentId, bytes)\n })\n .catch(() => {})\n }\n }, [documentId, isDraft, ready])\n async function saveVersion() {\n if (!ready || savingRef.current || stream) return false\n if (snapshot || !ready.canEdit) return true\n if (offline) return false\n savingRef.current = true\n setSaving(true)\n try {\n if (!flushInputRef.current) throw new Error('The editor is not ready to save yet.')\n flushInputRef.current()\n runBeforeSave(ref.current)\n const atRevision = revision.current\n const result = isDraft\n ? await (async () => {\n const bytes = await ref.current?.save()\n if (!bytes) throw new Error('The editor is not ready.')\n return (\n await adapter.request(`/notes?${new URLSearchParams({ title })}`, {\n method: 'POST',\n headers: {\n 'Content-Type':\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n },\n body: bytes,\n })\n ).json() as Promise<{ document_ext_id: string }>\n })()\n : await adapter.save(documentId, ready.room ? encodeState(ready.room) : undefined)\n if (revision.current === atRevision) {\n dirtyRef.current = false\n setDirty(false)\n drafts.delete(documentId)\n }\n const savedVersion =\n 'version' in result && typeof result.version === 'number' ? result.version : undefined\n if (!isDraft && !savedVersion) throw new Error('Could not confirm the saved version.')\n await adapter.onVersionSaved?.(result.document_ext_id, savedVersion)\n onSaved?.(result.document_ext_id)\n if (revision.current !== atRevision) {\n adapter.notify?.('The document changed while saving. Please try again.', 'error')\n return false\n }\n adapter.notify?.(isDraft ? 'Word note saved' : 'DOCX version saved', 'success')\n return savedVersion ?? true\n } catch (e) {\n adapter.notify?.(e instanceof Error ? e.message : 'Could not save this document.', 'error')\n setStatus('Save failed \u00B7 your draft is retained')\n return false\n } finally {\n savingRef.current = false\n setSaving(false)\n }\n }\n useEffect(() => {\n if (!saveRef) return\n saveRef.current = saveVersion\n return () => {\n saveRef.current = null\n }\n })\n function editorReady(editor: Editor) {\n ref.current = editor\n if (streamRef.current) {\n streamWriter.current = new WordDraftStream(editor)\n updateStream()\n }\n fitCleanup.current?.()\n fitted.current = undefined\n const viewport = stageRef.current?.querySelector<HTMLElement>('.native-docx-viewport')\n if (!viewport) return\n let surface: Element | null = null\n const fit = () => {\n // The page itself: laid out after the editor is ready, and resized by every zoom.\n const page = viewport.querySelector('.docx-paginated-surface')\n if (page && page !== surface) resize.observe((surface = page))\n const current = editor.getZoom()\n // A zoom the fit did not apply is the reader's: stop fitting until they pick Fit width again.\n if (\n fitting.current &&\n fitted.current !== undefined &&\n Math.abs(current - fitted.current) > 0.001\n )\n fitting.current = false\n setFitWidth(fitting.current)\n setZoomPercent(Math.round(current * 100))\n if (!fitting.current) return\n const pageWidth = editor.getPageGeometry()[0]?.box.width\n if (!pageWidth) return\n const style = getComputedStyle(viewport)\n const available =\n viewport.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight)\n // The page fills the viewer, its padding the only gutter. Compact (an email body) never\n // magnifies: its text stays the size the email is read at.\n const zoom = Math.max(0.1, Math.min(compact ? 1 : 5, available / pageWidth))\n if (Math.abs(current - zoom) > 0.001) editor.setZoom(zoom)\n fitted.current = editor.getZoom()\n setZoomPercent(Math.round(fitted.current * 100))\n }\n refit.current = fit\n const resize = new ResizeObserver(fit)\n const chrome = new MutationObserver(fit)\n resize.observe(viewport)\n chrome.observe(viewport, {\n attributes: true,\n attributeFilter: ['style', 'data-review-pane', 'data-review-margin'],\n })\n // Where the page mounts, to start watching it if it is laid out after the editor is ready.\n const mount = viewport.querySelector('.docx-content-mount')\n if (mount) chrome.observe(mount, { childList: true })\n if (!fitting.current) editor.setZoom(zoomPercent / 100)\n fit()\n fitCleanup.current = () => {\n resize.disconnect()\n chrome.disconnect()\n refit.current = undefined\n }\n }\n function pickZoom(value: string) {\n const editor = ref.current\n if (!editor) return\n if (value === 'fit') {\n fitting.current = true\n fitted.current = undefined\n refit.current?.()\n return\n }\n fitting.current = false\n setFitWidth(false)\n setZoomPercent(Number(value))\n editor.setZoom(Number(value) / 100)\n }\n function changed() {\n if (snapshot) return\n revision.current += 1\n dirtyRef.current = true\n setDirty(true)\n setStatus(\n isDraft ? 'Unsaved note' : offline ? 'Offline \u00B7 edits buffered locally' : 'Saving changes\u2026'\n )\n if (isDraft) {\n clearTimeout(draftTimer.current)\n draftTimer.current = setTimeout(() => {\n void ref.current?.save().then((bytes) => {\n if (bytes) drafts.set(documentId, bytes)\n })\n }, 200)\n }\n }\n return (\n <section\n className={compact ? 'native-docx-viewer native-docx-compact' : 'native-docx-viewer'}\n data-testid=\"native-docx-editor\"\n aria-busy={!!stream?.busy}\n data-generation-state={\n stream ? (stream.busy ? 'generating' : stream.error ? 'stopped' : 'generated') : 'ready'\n }\n >\n {offline && (\n <div className=\"native-docx-notice\">\n Changes are buffered in this browser. Keep this tab open until the connection returns, or\n download your DOCX.\n </div>\n )}\n {error && (\n <div className=\"native-docx-notice\" data-error=\"true\" role=\"alert\">\n {error}{' '}\n <button\n disabled={!stream && dirty}\n title={dirty ? 'Download your unsaved DOCX before reopening the editor' : undefined}\n onClick={() =>\n stream ? (setError(''), setStreamAttempt((x) => x + 1)) : setRetry((x) => x + 1)\n }\n >\n <RefreshCw size={12} />\n Retry\n </button>\n </div>\n )}\n {!ready && !error && (\n <div className=\"native-docx-error\" role=\"status\">\n Opening Word document\u2026\n </div>\n )}\n {ready && (\n <div className=\"native-docx-body docx-editor\">\n <EditorBoundary key={retry}>\n <DocxEditor.Root\n document={ready.document}\n modules={ready.modules}\n fonts={ready.fonts}\n mode={\n stream || (isDraft && ready.canEdit && !snapshot) || (compact && ready.canEdit)\n ? 'edit'\n : !ready.canEdit || snapshot\n ? 'view'\n : 'suggesting'\n }\n reviewDisplayMode=\"all-markup\"\n zoomMode={fixedZoomMode}\n author={ready.author}\n onReady={editorReady}\n onChange={(change) => {\n if (change.source !== 'load') changed()\n }}\n onFontError={(e) => setError(e.message)}\n >\n <DocxAuthorContext.Provider value={ready.author}>\n <DefinedTermsProvider\n load={adapter.definitions}\n editable={!stream && !snapshot && ready.canEdit}\n notify={adapter.notify}\n >\n <HouseTemplateProvider\n enabled={!stream}\n host={adapter.houseTemplate}\n documentId={isDraft || snapshot ? undefined : documentId}\n editable={!stream && !snapshot && ready.canEdit}\n notify={adapter.notify}\n >\n <CrossReferencesProvider\n editable={!stream && !snapshot && ready.canEdit}\n references={adapter.references}\n documentId={documentId}\n notify={adapter.notify}\n >\n <SignatureFieldsProvider\n signers={adapter.signatureSigners}\n mySignature={adapter.savedSignature}\n editable={!stream && !snapshot && ready.canEdit}\n notify={adapter.notify}\n >\n <DocxEditor.RevisionMarkup\n insertions={{ mark: 'underline', color: 'blue' }}\n deletions={{ mark: 'strikethrough', color: 'red' }}\n movedFrom={{ mark: 'doubleStrikethrough', color: 'green' }}\n movedTo={{ mark: 'doubleUnderline', color: 'green' }}\n trackMoves\n />\n {compact && !stream && <CompactToolbar />}\n {!compact && !stream && (\n <DocxCommandMenu\n onSave={() => void saveVersion()}\n imageGeneration={\n adapter.imageGeneration && {\n notify: adapter.notify,\n ...adapter.imageGeneration,\n }\n }\n badge={\n // The document's state, in place of a title row above the ribbon.\n <DocumentStateBadge\n state={\n snapshot || !ready.canEdit\n ? 'read-only'\n : ready.room\n ? 'co-editing'\n : isDraft\n ? 'draft'\n : undefined\n }\n />\n }\n />\n )}\n {!stream && <WordShortcuts scope={stageRef} />}\n {!stream && <TableTabKeys scope={stageRef} />}\n <div\n className=\"native-docx-stage\"\n ref={stageRef}\n onMouseDownCapture={(event) => {\n if (event.button === 2 && ref.current?.getSelectionPlacement())\n event.preventDefault()\n }}\n >\n <DocxEditor.Viewport className=\"native-docx-viewport\">\n <DocxEditor.Content />\n <DocxMentions\n initialCommentId={initialCommentId}\n mentions={adapter.mentions}\n notify={adapter.notify}\n getAgentStatus={adapter.getAgentStatus}\n requestAgent={\n adapter.requestAgent\n ? (request) => adapter.requestAgent!(documentId, request)\n : undefined\n }\n >\n <RoomInputBinding\n session={ready.room?.session}\n flushRef={flushInputRef}\n />\n <AgentUndoRoom.Provider value={ready.room?.ydoc ?? null}>\n <DocxEditorReview>\n {() => (\n <DocxEditorReview.Card>\n <DocxCommentActivity />\n <AgentUndo />\n </DocxEditorReview.Card>\n )}\n </DocxEditorReview>\n </AgentUndoRoom.Provider>\n </DocxMentions>\n {!compact && <DocxEditor.HeaderFooterChrome />}\n {!compact && <DocxEditor.NotesChrome />}\n <DocxEditor.Equation />\n <DocxEditor.HyperLink />\n <DocxEditor.ContextMenu>\n <DocxContextMenuExtras />\n <MySignatureContextItems />\n <SignatureFieldContextItem />\n </DocxEditor.ContextMenu>\n </DocxEditor.Viewport>\n {!compact && <DocxEditor.PageNumber />}\n </div>\n </SignatureFieldsProvider>\n </CrossReferencesProvider>\n </HouseTemplateProvider>\n </DefinedTermsProvider>\n </DocxAuthorContext.Provider>\n </DocxEditor.Root>\n </EditorBoundary>\n </div>\n )}\n <div className=\"native-docx-actions\">\n <span className=\"native-docx-status\" role=\"status\">\n {offline ? <WifiOff size={14} /> : !dirty && ready ? <Check size={14} /> : null}\n {status}\n </span>\n <DocxParticipants session={ready?.room?.session} />\n {!compact && (\n <select\n className=\"native-docx-zoom\"\n aria-label=\"Zoom\"\n data-testid=\"native-docx-zoom\"\n disabled={!ready}\n value={fitWidth ? 'fit' : String(zoomPercent)}\n onChange={(event) => pickZoom(event.target.value)}\n >\n <option value=\"fit\">Fit width</option>\n {[...new Set([...ZOOM_LEVELS, ...(fitWidth ? [] : [zoomPercent])])]\n .sort((a, b) => a - b)\n .map((level) => (\n <option key={level} value={String(level)}>\n {level}%\n </option>\n ))}\n </select>\n )}\n {!compact && (\n <button\n onClick={() => void exportDocument()}\n disabled={!ready}\n aria-label=\"Download DOCX\"\n >\n <Download size={14} />\n DOCX\n </button>\n )}\n {!compact && !snapshot && !stream && ready?.canEdit && (\n <button\n className=\"native-docx-save\"\n onClick={() => void saveVersion()}\n disabled={!ready || saving || offline}\n data-testid=\"native-docx-save\"\n >\n <Save size={14} />\n {saving ? 'Saving\u2026' : isDraft ? 'Save note' : 'Save version'}\n </button>\n )}\n </div>\n </section>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,7 @@ import React from 'react';
|
|
|
5
5
|
* press outside it. `children` may be a function that receives `close`, for panels that close
|
|
6
6
|
* themselves once the user has picked something.
|
|
7
7
|
*/
|
|
8
|
-
export declare function RibbonMenu({ label, icon, children, className, testId, title, keepMounted, popoverClassName, }: {
|
|
8
|
+
export declare function RibbonMenu({ label, icon, children, className, testId, title, keepMounted, popoverClassName, restoreFocus, }: {
|
|
9
9
|
label: string;
|
|
10
10
|
/** Tooltip; defaults to `label`. */
|
|
11
11
|
title?: string;
|
|
@@ -17,4 +17,6 @@ export declare function RibbonMenu({ label, icon, children, className, testId, t
|
|
|
17
17
|
/** Keep the panel's content mounted (hidden) while closed, so its controls keep their state. */
|
|
18
18
|
keepMounted?: boolean;
|
|
19
19
|
popoverClassName?: string;
|
|
20
|
+
/** Return keyboard focus to the trigger when Escape closes this menu. */
|
|
21
|
+
restoreFocus?: boolean;
|
|
20
22
|
}): React.JSX.Element;
|
package/dist/docx/RibbonMenu.js
CHANGED
|
@@ -9,17 +9,23 @@ function RibbonMenu({
|
|
|
9
9
|
testId,
|
|
10
10
|
title,
|
|
11
11
|
keepMounted = false,
|
|
12
|
-
popoverClassName
|
|
12
|
+
popoverClassName,
|
|
13
|
+
restoreFocus = false
|
|
13
14
|
}) {
|
|
14
15
|
const [open, setOpen] = useState(false);
|
|
15
16
|
const element = useRef(null);
|
|
17
|
+
const trigger = useRef(null);
|
|
16
18
|
useEffect(() => {
|
|
17
19
|
if (!open) return;
|
|
18
20
|
const dismiss = (event) => {
|
|
19
21
|
if (!element.current?.contains(event.target)) setOpen(false);
|
|
20
22
|
};
|
|
21
23
|
const escape = (event) => {
|
|
22
|
-
if (event.key === "Escape")
|
|
24
|
+
if (event.key === "Escape") {
|
|
25
|
+
if (restoreFocus && element.current?.contains(document.activeElement))
|
|
26
|
+
trigger.current?.focus();
|
|
27
|
+
setOpen(false);
|
|
28
|
+
}
|
|
23
29
|
};
|
|
24
30
|
document.addEventListener("pointerdown", dismiss);
|
|
25
31
|
document.addEventListener("keydown", escape);
|
|
@@ -27,12 +33,13 @@ function RibbonMenu({
|
|
|
27
33
|
document.removeEventListener("pointerdown", dismiss);
|
|
28
34
|
document.removeEventListener("keydown", escape);
|
|
29
35
|
};
|
|
30
|
-
}, [open]);
|
|
36
|
+
}, [open, restoreFocus]);
|
|
31
37
|
return /* @__PURE__ */ jsxs("div", { className: "native-docx-ribbon-menu", ref: element, children: [
|
|
32
38
|
/* @__PURE__ */ jsx(
|
|
33
39
|
"button",
|
|
34
40
|
{
|
|
35
41
|
type: "button",
|
|
42
|
+
ref: trigger,
|
|
36
43
|
className: ["native-docx-ribbon-trigger", className].filter(Boolean).join(" "),
|
|
37
44
|
"aria-label": label,
|
|
38
45
|
title: title ?? label,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/docx/RibbonMenu.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useEffect, useRef, useState } from 'react'\n\n/**\n * A ribbon button that opens a panel under the ribbon (Font, More formatting, the style gallery).\n * Pressing the trigger never takes the caret out of the document; the panel closes on Escape or a\n * press outside it. `children` may be a function that receives `close`, for panels that close\n * themselves once the user has picked something.\n */\nexport function RibbonMenu({\n label,\n icon,\n children,\n className,\n testId,\n title,\n keepMounted = false,\n popoverClassName,\n}: {\n label: string\n /** Tooltip; defaults to `label`. */\n title?: string\n /** Trigger content: an icon, or a short text label with a `className` that widens it. */\n icon: React.ReactNode\n children: React.ReactNode | ((close: () => void) => React.ReactNode)\n className?: string\n testId?: string\n /** Keep the panel's content mounted (hidden) while closed, so its controls keep their state. */\n keepMounted?: boolean\n popoverClassName?: string\n}) {\n const [open, setOpen] = useState(false)\n const element = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!open) return\n const dismiss = (event: PointerEvent) => {\n if (!element.current?.contains(event.target as Node)) setOpen(false)\n }\n const escape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setOpen(false)\n }\n document.addEventListener('pointerdown', dismiss)\n document.addEventListener('keydown', escape)\n return () => {\n document.removeEventListener('pointerdown', dismiss)\n document.removeEventListener('keydown', escape)\n }\n }, [open])\n return (\n <div className=\"native-docx-ribbon-menu\" ref={element}>\n <button\n type=\"button\"\n className={['native-docx-ribbon-trigger', className].filter(Boolean).join(' ')}\n aria-label={label}\n title={title ?? label}\n aria-expanded={open}\n data-testid={testId}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setOpen((value) => !value)}\n >\n {icon}\n </button>\n {(open || keepMounted) && (\n <div\n className={['native-docx-ribbon-popover', popoverClassName].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={label}\n hidden={!open}\n onMouseDown={(event) => {\n if (!(\n event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement\n ))\n event.preventDefault()\n }}\n >\n {typeof children === 'function' ? children(() => setOpen(false)) : children}\n </div>\n )}\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["import React, { useEffect, useRef, useState } from 'react'\n\n/**\n * A ribbon button that opens a panel under the ribbon (Font, More formatting, the style gallery).\n * Pressing the trigger never takes the caret out of the document; the panel closes on Escape or a\n * press outside it. `children` may be a function that receives `close`, for panels that close\n * themselves once the user has picked something.\n */\nexport function RibbonMenu({\n label,\n icon,\n children,\n className,\n testId,\n title,\n keepMounted = false,\n popoverClassName,\n restoreFocus = false,\n}: {\n label: string\n /** Tooltip; defaults to `label`. */\n title?: string\n /** Trigger content: an icon, or a short text label with a `className` that widens it. */\n icon: React.ReactNode\n children: React.ReactNode | ((close: () => void) => React.ReactNode)\n className?: string\n testId?: string\n /** Keep the panel's content mounted (hidden) while closed, so its controls keep their state. */\n keepMounted?: boolean\n popoverClassName?: string\n /** Return keyboard focus to the trigger when Escape closes this menu. */\n restoreFocus?: boolean\n}) {\n const [open, setOpen] = useState(false)\n const element = useRef<HTMLDivElement>(null)\n const trigger = useRef<HTMLButtonElement>(null)\n useEffect(() => {\n if (!open) return\n const dismiss = (event: PointerEvent) => {\n if (!element.current?.contains(event.target as Node)) setOpen(false)\n }\n const escape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n if (restoreFocus && element.current?.contains(document.activeElement))\n trigger.current?.focus()\n setOpen(false)\n }\n }\n document.addEventListener('pointerdown', dismiss)\n document.addEventListener('keydown', escape)\n return () => {\n document.removeEventListener('pointerdown', dismiss)\n document.removeEventListener('keydown', escape)\n }\n }, [open, restoreFocus])\n return (\n <div className=\"native-docx-ribbon-menu\" ref={element}>\n <button\n type=\"button\"\n ref={trigger}\n className={['native-docx-ribbon-trigger', className].filter(Boolean).join(' ')}\n aria-label={label}\n title={title ?? label}\n aria-expanded={open}\n data-testid={testId}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setOpen((value) => !value)}\n >\n {icon}\n </button>\n {(open || keepMounted) && (\n <div\n className={['native-docx-ribbon-popover', popoverClassName].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={label}\n hidden={!open}\n onMouseDown={(event) => {\n if (!(\n event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement\n ))\n event.preventDefault()\n }}\n >\n {typeof children === 'function' ? children(() => setOpen(false)) : children}\n </div>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAwDI,SACE,KADF;AAxDJ,SAAgB,WAAW,QAAQ,gBAAgB;AAQ5C,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,eAAe;AACjB,GAcG;AACD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,UAAU,OAA0B,IAAI;AAC9C,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,UAAU,CAAC,UAAwB;AACvC,UAAI,CAAC,QAAQ,SAAS,SAAS,MAAM,MAAc,EAAG,SAAQ,KAAK;AAAA,IACrE;AACA,UAAM,SAAS,CAAC,UAAyB;AACvC,UAAI,MAAM,QAAQ,UAAU;AAC1B,YAAI,gBAAgB,QAAQ,SAAS,SAAS,SAAS,aAAa;AAClE,kBAAQ,SAAS,MAAM;AACzB,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AACA,aAAS,iBAAiB,eAAe,OAAO;AAChD,aAAS,iBAAiB,WAAW,MAAM;AAC3C,WAAO,MAAM;AACX,eAAS,oBAAoB,eAAe,OAAO;AACnD,eAAS,oBAAoB,WAAW,MAAM;AAAA,IAChD;AAAA,EACF,GAAG,CAAC,MAAM,YAAY,CAAC;AACvB,SACE,qBAAC,SAAI,WAAU,2BAA0B,KAAK,SAC5C;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,KAAK;AAAA,QACL,WAAW,CAAC,8BAA8B,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAC7E,cAAY;AAAA,QACZ,OAAO,SAAS;AAAA,QAChB,iBAAe;AAAA,QACf,eAAa;AAAA,QACb,aAAa,CAAC,UAAU,MAAM,eAAe;AAAA,QAC7C,SAAS,MAAM,QAAQ,CAAC,UAAU,CAAC,KAAK;AAAA,QAEvC;AAAA;AAAA,IACH;AAAA,KACE,QAAQ,gBACR;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,CAAC,8BAA8B,gBAAgB,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QACpF,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,QAAQ,CAAC;AAAA,QACT,aAAa,CAAC,UAAU;AACtB,cAAI,EACF,MAAM,kBAAkB,oBAAoB,MAAM,kBAAkB;AAEpE,kBAAM,eAAe;AAAA,QACzB;AAAA,QAEC,iBAAO,aAAa,aAAa,SAAS,MAAM,QAAQ,KAAK,CAAC,IAAI;AAAA;AAAA,IACrE;AAAA,KAEJ;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* state while the menu is closed).
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
10
|
+
export declare function NamedCommandList({ children }: {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}): React.JSX.Element;
|
|
10
13
|
/**
|
|
11
14
|
* The row of one ribbon tab. `tab` names the tab shown, so the More menu closes and the row is
|
|
12
15
|
* measured afresh when it changes.
|
|
@@ -15,6 +15,10 @@ import { Ellipsis } from "lucide-react";
|
|
|
15
15
|
import { RibbonMenu } from "./RibbonMenu.js";
|
|
16
16
|
import { planOverflow } from "./overflowPlan.js";
|
|
17
17
|
const Overflow = createContext(null);
|
|
18
|
+
const NamedCommands = createContext(false);
|
|
19
|
+
function NamedCommandList({ children }) {
|
|
20
|
+
return /* @__PURE__ */ jsx(NamedCommands.Provider, { value: true, children });
|
|
21
|
+
}
|
|
18
22
|
const MORE_WIDTH = 32;
|
|
19
23
|
const sameSet = (a, b) => a.size === b.size && [...a].every((id) => b.has(id));
|
|
20
24
|
function RibbonOverflow({ tab, children }) {
|
|
@@ -136,13 +140,31 @@ function RibbonItem({
|
|
|
136
140
|
children
|
|
137
141
|
}) {
|
|
138
142
|
const context = useContext(Overflow);
|
|
143
|
+
const named = useContext(NamedCommands);
|
|
139
144
|
const element = useRef(null);
|
|
140
145
|
const register = context?.register;
|
|
141
146
|
useLayoutEffect(() => {
|
|
142
147
|
if (!register || !element.current) return;
|
|
143
148
|
return register(id, { label, priority, element: element.current });
|
|
144
149
|
}, [register, id, label, priority]);
|
|
145
|
-
if (!context)
|
|
150
|
+
if (!context) {
|
|
151
|
+
if (!named) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
152
|
+
return /* @__PURE__ */ jsxs(
|
|
153
|
+
"span",
|
|
154
|
+
{
|
|
155
|
+
className: "native-docx-command-item",
|
|
156
|
+
"data-ribbon-item": id,
|
|
157
|
+
onClick: (event) => {
|
|
158
|
+
if (event.target.classList.contains("native-docx-command-label"))
|
|
159
|
+
event.currentTarget.querySelector("button:not([disabled])")?.click();
|
|
160
|
+
},
|
|
161
|
+
children: [
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: "native-docx-command-control", children }),
|
|
163
|
+
/* @__PURE__ */ jsx("span", { className: "native-docx-command-label", children: label })
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
}
|
|
146
168
|
const collapsed = context.collapsed.has(id);
|
|
147
169
|
const slot = context.slots[id];
|
|
148
170
|
return /* @__PURE__ */ jsx(
|
|
@@ -157,6 +179,7 @@ function RibbonItem({
|
|
|
157
179
|
);
|
|
158
180
|
}
|
|
159
181
|
export {
|
|
182
|
+
NamedCommandList,
|
|
160
183
|
RibbonItem,
|
|
161
184
|
RibbonOverflow
|
|
162
185
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/docx/RibbonOverflow.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * A ribbon tab's row of controls that never crowds: what does not fit collapses into a trailing\n * \"\u2026\" (More) menu, as Word's ribbon does. Each control is a `RibbonItem` with a label and a\n * priority; the row measures the controls (ResizeObserver) and collapses the lowest priority\n * first, the rightmost first among equals. A collapsed control is the same component, moved by a\n * portal into its row of the More menu, beside its label, so it keeps working (and keeps its\n * state while the menu is closed).\n */\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { Ellipsis } from 'lucide-react'\nimport { RibbonMenu } from './RibbonMenu'\nimport { planOverflow } from './overflowPlan'\n\ninterface Registered {\n label: string\n priority: number\n element: HTMLElement\n}\n\ninterface OverflowContext {\n collapsed: ReadonlySet<string>\n slots: Readonly<Record<string, HTMLElement>>\n register: (id: string, item: Registered) => () => void\n}\n\nconst Overflow = createContext<OverflowContext | null>(null)\n\n/** Room for the More trigger: its 28 px button and the row's gap. */\nconst MORE_WIDTH = 32\n\nconst sameSet = (a: ReadonlySet<string>, b: ReadonlySet<string>) =>\n a.size === b.size && [...a].every((id) => b.has(id))\n\n/**\n * The row of one ribbon tab. `tab` names the tab shown, so the More menu closes and the row is\n * measured afresh when it changes.\n */\nexport function RibbonOverflow({ tab, children }: { tab: string; children: React.ReactNode }) {\n const row = useRef<HTMLDivElement>(null)\n const items = useRef(new Map<string, Registered>())\n const widths = useRef(new Map<string, number>())\n const [version, setVersion] = useState(0)\n const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(() => new Set())\n const [slots, setSlots] = useState<Record<string, HTMLElement>>({})\n // In ribbon order, with their labels, for the More menu's rows.\n const [menu, setMenu] = useState<readonly { id: string; label: string }[]>([])\n\n const register = useCallback((id: string, item: Registered) => {\n items.current.set(id, item)\n setVersion((v) => v + 1)\n return () => {\n if (items.current.get(id) === item) items.current.delete(id)\n setVersion((v) => v + 1)\n }\n }, [])\n\n const plan = useCallback(() => {\n const element = row.current\n if (!element) return\n const gap = parseFloat(getComputedStyle(element).columnGap) || 0\n const ordered = Array.from(element.querySelectorAll<HTMLElement>('[data-ribbon-item]'))\n .map((node) => node.dataset.ribbonItem!)\n .filter((id) => items.current.has(id))\n const measured = ordered.map((id) => {\n const { element: node, priority } = items.current.get(id)!\n if (!node.hidden) {\n const width = node.getBoundingClientRect().width\n // A control that draws nothing (an action the host does not offer) takes no room.\n widths.current.set(id, width ? width + gap : 0)\n }\n return { id, priority, width: widths.current.get(id) ?? 0 }\n })\n const next = planOverflow(measured, element.clientWidth, MORE_WIDTH)\n setCollapsed((current) => (sameSet(current, next) ? current : next))\n const entries = ordered\n .filter((id) => next.has(id))\n .map((id) => ({ id, label: items.current.get(id)!.label }))\n setMenu((current) =>\n current.length === entries.length &&\n current.every((entry, i) => entry.id === entries[i].id && entry.label === entries[i].label)\n ? current\n : entries\n )\n }, [])\n\n useLayoutEffect(plan, [plan, version, tab, collapsed])\n\n useLayoutEffect(() => {\n const element = row.current\n if (!element) return\n const observer = new ResizeObserver(() => plan())\n observer.observe(element)\n for (const item of items.current.values()) observer.observe(item.element)\n return () => observer.disconnect()\n }, [plan, version])\n\n const slotRef = useCallback(\n (id: string) => (node: HTMLElement | null) =>\n setSlots((current) => {\n if (node ? current[id] === node : !(id in current)) return current\n const next = { ...current }\n if (node) next[id] = node\n else delete next[id]\n return next\n }),\n []\n )\n\n const context = useMemo(() => ({ collapsed, slots, register }), [collapsed, slots, register])\n const shown = menu.filter((entry) => collapsed.has(entry.id))\n\n return (\n <Overflow.Provider value={context}>\n <div className=\"native-docx-ribbon-row\" ref={row} data-testid=\"docx-ribbon-row\">\n {children}\n {shown.length > 0 && (\n <RibbonMenu\n key={tab}\n label=\"More\"\n title=\"More commands\"\n icon={<Ellipsis size={16} />}\n testId=\"docx-ribbon-more\"\n keepMounted\n popoverClassName=\"native-docx-ribbon-more\"\n >\n {(close) => <MoreRows entries={shown} slotRef={slotRef} close={close} />}\n </RibbonMenu>\n )}\n </div>\n </Overflow.Provider>\n )\n}\n\nfunction MoreRows({\n entries,\n slotRef,\n close,\n}: {\n entries: readonly { id: string; label: string }[]\n slotRef: (id: string) => (node: HTMLElement | null) => void\n close: () => void\n}) {\n // One stable ref callback per id, so React does not detach and reattach the slots each render.\n const refs = useRef(new Map<string, (node: HTMLElement | null) => void>())\n const refFor = (id: string) => {\n let ref = refs.current.get(id)\n if (!ref) refs.current.set(id, (ref = slotRef(id)))\n return ref\n }\n // A DOM listener, not a React one: the controls are portalled in, so React would route their\n // clicks through the ribbon row they belong to, not through this list. Capture, because an\n // engine control may stop its click from bubbling.\n const list = useRef<HTMLDivElement>(null)\n const latest = useRef(close)\n latest.current = close\n useEffect(() => {\n const element = list.current\n if (!element) return\n const onClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n const row = target.closest<HTMLElement>('.native-docx-ribbon-more-row')\n if (!row) return\n const control = row.querySelector<HTMLElement>('.native-docx-ribbon-more-control')!\n if (!control.contains(target)) {\n // The label is part of the row: it presses the control.\n control.querySelector<HTMLElement>('button:not([disabled])')?.click()\n return\n }\n // A plain command closes the menu, as Word's does; a control that opens its own panel (a\n // gallery, a picker) keeps it open.\n const button = target.closest('button')\n if (\n button &&\n !button.disabled &&\n !control.querySelector('.native-docx-ribbon-popover')?.contains(button) &&\n !button.hasAttribute('aria-expanded') &&\n !button.hasAttribute('aria-haspopup')\n )\n latest.current()\n }\n element.addEventListener('click', onClick, true)\n return () => element.removeEventListener('click', onClick, true)\n }, [])\n return (\n <div className=\"native-docx-ribbon-more-list\" ref={list}>\n {entries.map((entry) => (\n <div className=\"native-docx-ribbon-more-row\" key={entry.id} data-ribbon-more={entry.id}>\n <span className=\"native-docx-ribbon-more-control\" ref={refFor(entry.id)} />\n <span className=\"native-docx-ribbon-more-label\">{entry.label}</span>\n </div>\n ))}\n </div>\n )\n}\n\n/**\n * One control of a ribbon row. `label` names it in the More menu; `priority` (default 0) decides\n * what collapses first. Outside a `RibbonOverflow` it renders its children as they are.\n */\nexport function RibbonItem({\n id,\n label,\n priority = 0,\n children,\n}: {\n id: string\n label: string\n priority?: number\n children: React.ReactNode\n}) {\n const context = useContext(Overflow)\n const element = useRef<HTMLSpanElement>(null)\n const register = context?.register\n useLayoutEffect(() => {\n if (!register || !element.current) return\n return register(id, { label, priority, element: element.current })\n }, [register, id, label, priority])\n if (!context) return <>{children}</>\n const collapsed = context.collapsed.has(id)\n const slot = context.slots[id]\n return (\n <span\n ref={element}\n className=\"native-docx-ribbon-item\"\n data-ribbon-item={id}\n hidden={collapsed || undefined}\n >\n {collapsed ? (slot ? createPortal(children, slot) : null) : children}\n </span>\n )\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["/**\n * A ribbon tab's row of controls that never crowds: what does not fit collapses into a trailing\n * \"\u2026\" (More) menu, as Word's ribbon does. Each control is a `RibbonItem` with a label and a\n * priority; the row measures the controls (ResizeObserver) and collapses the lowest priority\n * first, the rightmost first among equals. A collapsed control is the same component, moved by a\n * portal into its row of the More menu, beside its label, so it keeps working (and keeps its\n * state while the menu is closed).\n */\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { Ellipsis } from 'lucide-react'\nimport { RibbonMenu } from './RibbonMenu'\nimport { planOverflow } from './overflowPlan'\n\ninterface Registered {\n label: string\n priority: number\n element: HTMLElement\n}\n\ninterface OverflowContext {\n collapsed: ReadonlySet<string>\n slots: Readonly<Record<string, HTMLElement>>\n register: (id: string, item: Registered) => () => void\n}\n\nconst Overflow = createContext<OverflowContext | null>(null)\n\n/** Render the same command controls with their visible names in the editor menu. */\nconst NamedCommands = createContext(false)\nexport function NamedCommandList({ children }: { children: React.ReactNode }) {\n return <NamedCommands.Provider value>{children}</NamedCommands.Provider>\n}\n\n/** Room for the More trigger: its 28 px button and the row's gap. */\nconst MORE_WIDTH = 32\n\nconst sameSet = (a: ReadonlySet<string>, b: ReadonlySet<string>) =>\n a.size === b.size && [...a].every((id) => b.has(id))\n\n/**\n * The row of one ribbon tab. `tab` names the tab shown, so the More menu closes and the row is\n * measured afresh when it changes.\n */\nexport function RibbonOverflow({ tab, children }: { tab: string; children: React.ReactNode }) {\n const row = useRef<HTMLDivElement>(null)\n const items = useRef(new Map<string, Registered>())\n const widths = useRef(new Map<string, number>())\n const [version, setVersion] = useState(0)\n const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(() => new Set())\n const [slots, setSlots] = useState<Record<string, HTMLElement>>({})\n // In ribbon order, with their labels, for the More menu's rows.\n const [menu, setMenu] = useState<readonly { id: string; label: string }[]>([])\n\n const register = useCallback((id: string, item: Registered) => {\n items.current.set(id, item)\n setVersion((v) => v + 1)\n return () => {\n if (items.current.get(id) === item) items.current.delete(id)\n setVersion((v) => v + 1)\n }\n }, [])\n\n const plan = useCallback(() => {\n const element = row.current\n if (!element) return\n const gap = parseFloat(getComputedStyle(element).columnGap) || 0\n const ordered = Array.from(element.querySelectorAll<HTMLElement>('[data-ribbon-item]'))\n .map((node) => node.dataset.ribbonItem!)\n .filter((id) => items.current.has(id))\n const measured = ordered.map((id) => {\n const { element: node, priority } = items.current.get(id)!\n if (!node.hidden) {\n const width = node.getBoundingClientRect().width\n // A control that draws nothing (an action the host does not offer) takes no room.\n widths.current.set(id, width ? width + gap : 0)\n }\n return { id, priority, width: widths.current.get(id) ?? 0 }\n })\n const next = planOverflow(measured, element.clientWidth, MORE_WIDTH)\n setCollapsed((current) => (sameSet(current, next) ? current : next))\n const entries = ordered\n .filter((id) => next.has(id))\n .map((id) => ({ id, label: items.current.get(id)!.label }))\n setMenu((current) =>\n current.length === entries.length &&\n current.every((entry, i) => entry.id === entries[i].id && entry.label === entries[i].label)\n ? current\n : entries\n )\n }, [])\n\n useLayoutEffect(plan, [plan, version, tab, collapsed])\n\n useLayoutEffect(() => {\n const element = row.current\n if (!element) return\n const observer = new ResizeObserver(() => plan())\n observer.observe(element)\n for (const item of items.current.values()) observer.observe(item.element)\n return () => observer.disconnect()\n }, [plan, version])\n\n const slotRef = useCallback(\n (id: string) => (node: HTMLElement | null) =>\n setSlots((current) => {\n if (node ? current[id] === node : !(id in current)) return current\n const next = { ...current }\n if (node) next[id] = node\n else delete next[id]\n return next\n }),\n []\n )\n\n const context = useMemo(() => ({ collapsed, slots, register }), [collapsed, slots, register])\n const shown = menu.filter((entry) => collapsed.has(entry.id))\n\n return (\n <Overflow.Provider value={context}>\n <div className=\"native-docx-ribbon-row\" ref={row} data-testid=\"docx-ribbon-row\">\n {children}\n {shown.length > 0 && (\n <RibbonMenu\n key={tab}\n label=\"More\"\n title=\"More commands\"\n icon={<Ellipsis size={16} />}\n testId=\"docx-ribbon-more\"\n keepMounted\n popoverClassName=\"native-docx-ribbon-more\"\n >\n {(close) => <MoreRows entries={shown} slotRef={slotRef} close={close} />}\n </RibbonMenu>\n )}\n </div>\n </Overflow.Provider>\n )\n}\n\nfunction MoreRows({\n entries,\n slotRef,\n close,\n}: {\n entries: readonly { id: string; label: string }[]\n slotRef: (id: string) => (node: HTMLElement | null) => void\n close: () => void\n}) {\n // One stable ref callback per id, so React does not detach and reattach the slots each render.\n const refs = useRef(new Map<string, (node: HTMLElement | null) => void>())\n const refFor = (id: string) => {\n let ref = refs.current.get(id)\n if (!ref) refs.current.set(id, (ref = slotRef(id)))\n return ref\n }\n // A DOM listener, not a React one: the controls are portalled in, so React would route their\n // clicks through the ribbon row they belong to, not through this list. Capture, because an\n // engine control may stop its click from bubbling.\n const list = useRef<HTMLDivElement>(null)\n const latest = useRef(close)\n latest.current = close\n useEffect(() => {\n const element = list.current\n if (!element) return\n const onClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n const row = target.closest<HTMLElement>('.native-docx-ribbon-more-row')\n if (!row) return\n const control = row.querySelector<HTMLElement>('.native-docx-ribbon-more-control')!\n if (!control.contains(target)) {\n // The label is part of the row: it presses the control.\n control.querySelector<HTMLElement>('button:not([disabled])')?.click()\n return\n }\n // A plain command closes the menu, as Word's does; a control that opens its own panel (a\n // gallery, a picker) keeps it open.\n const button = target.closest('button')\n if (\n button &&\n !button.disabled &&\n !control.querySelector('.native-docx-ribbon-popover')?.contains(button) &&\n !button.hasAttribute('aria-expanded') &&\n !button.hasAttribute('aria-haspopup')\n )\n latest.current()\n }\n element.addEventListener('click', onClick, true)\n return () => element.removeEventListener('click', onClick, true)\n }, [])\n return (\n <div className=\"native-docx-ribbon-more-list\" ref={list}>\n {entries.map((entry) => (\n <div className=\"native-docx-ribbon-more-row\" key={entry.id} data-ribbon-more={entry.id}>\n <span className=\"native-docx-ribbon-more-control\" ref={refFor(entry.id)} />\n <span className=\"native-docx-ribbon-more-label\">{entry.label}</span>\n </div>\n ))}\n </div>\n )\n}\n\n/**\n * One control of a ribbon row. `label` names it in the More menu; `priority` (default 0) decides\n * what collapses first. Outside a `RibbonOverflow` it renders its children as they are.\n */\nexport function RibbonItem({\n id,\n label,\n priority = 0,\n children,\n}: {\n id: string\n label: string\n priority?: number\n children: React.ReactNode\n}) {\n const context = useContext(Overflow)\n const named = useContext(NamedCommands)\n const element = useRef<HTMLSpanElement>(null)\n const register = context?.register\n useLayoutEffect(() => {\n if (!register || !element.current) return\n return register(id, { label, priority, element: element.current })\n }, [register, id, label, priority])\n if (!context) {\n if (!named) return <>{children}</>\n return (\n <span\n className=\"native-docx-command-item\"\n data-ribbon-item={id}\n onClick={(event) => {\n if ((event.target as HTMLElement).classList.contains('native-docx-command-label'))\n event.currentTarget.querySelector<HTMLButtonElement>('button:not([disabled])')?.click()\n }}\n >\n <span className=\"native-docx-command-control\">{children}</span>\n <span className=\"native-docx-command-label\">{label}</span>\n </span>\n )\n }\n const collapsed = context.collapsed.has(id)\n const slot = context.slots[id]\n return (\n <span\n ref={element}\n className=\"native-docx-ribbon-item\"\n data-ribbon-item={id}\n hidden={collapsed || undefined}\n >\n {collapsed ? (slot ? createPortal(children, slot) : null) : children}\n </span>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|