@henryx/pagely 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/components/BlockMenu.vue.d.ts +27 -0
  2. package/dist/components/CodeBlockView.vue.d.ts +95 -0
  3. package/dist/components/ColAlignBadge.vue.d.ts +15 -0
  4. package/dist/components/ColorPanel.vue.d.ts +14 -0
  5. package/dist/components/CommentContentViewer.vue.d.ts +11 -0
  6. package/dist/components/CommentEditor.vue.d.ts +26 -0
  7. package/dist/components/DotFlowPadBlockView.vue.d.ts +146 -0
  8. package/dist/components/EmbedBlockShell.vue.d.ts +46 -0
  9. package/dist/components/EmbedFullscreenModal.vue.d.ts +29 -0
  10. package/dist/components/EmbedViewBlock.vue.d.ts +26 -0
  11. package/dist/components/EmbedViewToolbar.vue.d.ts +24 -0
  12. package/dist/components/ImageBlockView.vue.d.ts +7 -0
  13. package/dist/components/ImagePreviewDialog.vue.d.ts +13 -0
  14. package/dist/components/InsertLinkDialog.vue.d.ts +19 -0
  15. package/dist/components/InsertMenu.vue.d.ts +27 -0
  16. package/dist/components/LinkToolbar.vue.d.ts +15 -0
  17. package/dist/components/MathPopover.vue.d.ts +15 -0
  18. package/dist/components/MentionNode.vue.d.ts +92 -0
  19. package/dist/components/MermaidBlockView.vue.d.ts +104 -0
  20. package/dist/components/PagelyEditor.vue.d.ts +119 -0
  21. package/dist/components/PagelyViewer.vue.d.ts +15 -0
  22. package/dist/components/SelectionToolbar.vue.d.ts +23 -0
  23. package/dist/components/TableActionMenu.vue.d.ts +28 -0
  24. package/dist/components/TableSizePicker.vue.d.ts +19 -0
  25. package/dist/components/TableTools.vue.d.ts +45 -0
  26. package/dist/composables/useBlockButton.d.ts +21 -0
  27. package/dist/composables/useBlockConvert.d.ts +4 -0
  28. package/dist/composables/useBlockImageExport.d.ts +4 -0
  29. package/dist/composables/useBlockMenu.d.ts +19 -0
  30. package/dist/composables/useBlockOps.d.ts +3 -0
  31. package/dist/composables/useCodeMirror.d.ts +30 -0
  32. package/dist/composables/useCommentAnchors.d.ts +60 -0
  33. package/dist/composables/useCommentEditor.d.ts +24 -0
  34. package/dist/composables/useEditorCommands.d.ts +22 -0
  35. package/dist/composables/useEditorEvents.d.ts +22 -0
  36. package/dist/composables/useEmbedView.d.ts +28 -0
  37. package/dist/composables/useFileUpload.d.ts +28 -0
  38. package/dist/composables/useHeadingCollapse.d.ts +19 -0
  39. package/dist/composables/useHoverMenu.d.ts +7 -0
  40. package/dist/composables/useInsertButton.d.ts +7 -0
  41. package/dist/composables/useInsertMenu.d.ts +17 -0
  42. package/dist/composables/useLinkHover.d.ts +3 -0
  43. package/dist/composables/useLinkOps.d.ts +32 -0
  44. package/dist/composables/useMarkdownSync.d.ts +12 -0
  45. package/dist/composables/useMath.d.ts +38 -0
  46. package/dist/composables/useMention.d.ts +20 -0
  47. package/dist/composables/useMenuPosition.d.ts +13 -0
  48. package/dist/composables/useMenuSidePanel.d.ts +27 -0
  49. package/dist/composables/useNodeViewCommentAttrs.d.ts +12 -0
  50. package/dist/composables/usePagelyEditor.d.ts +17 -0
  51. package/dist/composables/useSelectionToolbar.d.ts +3 -0
  52. package/dist/composables/useTableCellOps.d.ts +21 -0
  53. package/dist/composables/useTableDots.d.ts +60 -0
  54. package/dist/composables/useTableTools.d.ts +72 -0
  55. package/dist/config/blockMenu/index.d.ts +39 -0
  56. package/dist/config/blockMenu/items.d.ts +26 -0
  57. package/dist/config/blockMenu/profiles.d.ts +13 -0
  58. package/dist/config/blockMenu/sections.d.ts +8 -0
  59. package/dist/config/blockMenu/tagMapping.d.ts +9 -0
  60. package/dist/config/blockTypeConfig.d.ts +1 -0
  61. package/dist/config/extensionProfiles.d.ts +3 -0
  62. package/dist/config/insertMenu/blockCommands.d.ts +2 -0
  63. package/dist/config/insertMenu/cellOps.d.ts +22 -0
  64. package/dist/config/insertMenu/commands.d.ts +16 -0
  65. package/dist/config/insertMenu/index.d.ts +10 -0
  66. package/dist/config/insertMenu/items.d.ts +11 -0
  67. package/dist/config/insertMenu/sections.d.ts +15 -0
  68. package/dist/config/selectionToolbarConfig.d.ts +25 -0
  69. package/dist/config/selectionToolbarRules.d.ts +5 -0
  70. package/dist/extensions/AutoLinkTitle.d.ts +2 -0
  71. package/dist/extensions/CodeBlockCM.d.ts +7 -0
  72. package/dist/extensions/CommentBlock.d.ts +3 -0
  73. package/dist/extensions/CommentMark.d.ts +5 -0
  74. package/dist/extensions/CommentableTableView.d.ts +7 -0
  75. package/dist/extensions/DotFlowPadBlock.d.ts +2 -0
  76. package/dist/extensions/EmbedView.d.ts +12 -0
  77. package/dist/extensions/Image.d.ts +15 -0
  78. package/dist/extensions/Mathematics.d.ts +3 -0
  79. package/dist/extensions/Mention.d.ts +13 -0
  80. package/dist/extensions/MermaidBlock.d.ts +2 -0
  81. package/dist/extensions/SlashInsert.d.ts +5 -0
  82. package/dist/extensions/SmartPaste.d.ts +14 -0
  83. package/dist/extensions/TableCellEnter.d.ts +2 -0
  84. package/dist/index.d.ts +41 -0
  85. package/dist/pagely.cjs +318 -0
  86. package/dist/pagely.js +24519 -0
  87. package/dist/stores/linkState.d.ts +21 -0
  88. package/dist/style.css +1 -0
  89. package/dist/types/menuCommands.d.ts +42 -0
  90. package/dist/utils/attachmentUpload.d.ts +15 -0
  91. package/dist/utils/commentIds.d.ts +1 -0
  92. package/dist/utils/embedView/attrs.d.ts +19 -0
  93. package/dist/utils/embedView/detect.d.ts +14 -0
  94. package/dist/utils/embedView/downgrade.d.ts +1 -0
  95. package/dist/utils/embedView/markdown.d.ts +6 -0
  96. package/dist/utils/embedView/metadata.d.ts +8 -0
  97. package/dist/utils/embedView/pagelyPreview.d.ts +1 -0
  98. package/dist/utils/embedView/url.d.ts +10 -0
  99. package/dist/utils/markdown-converter/shared.d.ts +15 -0
  100. package/dist/utils/markdown-converter/toHtml.d.ts +1 -0
  101. package/dist/utils/markdown-converter/toMarkdown.d.ts +7 -0
  102. package/dist/utils/markdown-converter.d.ts +4 -0
  103. package/dist/utils/paste/context.d.ts +4 -0
  104. package/dist/utils/paste/escape.d.ts +2 -0
  105. package/dist/utils/paste/handlers/codeBlock.d.ts +2 -0
  106. package/dist/utils/paste/handlers/dotFlowPad.d.ts +2 -0
  107. package/dist/utils/paste/handlers/jsonCode.d.ts +2 -0
  108. package/dist/utils/paste/handlers/latexBlock.d.ts +2 -0
  109. package/dist/utils/paste/handlers/markdown.d.ts +2 -0
  110. package/dist/utils/paste/handlers/mermaid.d.ts +2 -0
  111. package/dist/utils/paste/handlers/richHtml.d.ts +2 -0
  112. package/dist/utils/paste/handlers/tsv.d.ts +2 -0
  113. package/dist/utils/paste/index.d.ts +10 -0
  114. package/dist/utils/paste/parsers/json.d.ts +5 -0
  115. package/dist/utils/paste/parsers/tsv.d.ts +5 -0
  116. package/dist/utils/paste/richHtml.d.ts +1 -0
  117. package/dist/utils/paste/sanitize.d.ts +1 -0
  118. package/dist/utils/paste/types.d.ts +12 -0
  119. package/dist/utils/tableAlign.d.ts +2 -0
  120. package/package.json +99 -0
@@ -0,0 +1,22 @@
1
+ export interface UseEditorEventsOptions {
2
+ onBlockMouseMove: (event: MouseEvent) => void;
3
+ onBlockMouseLeave: () => void;
4
+ updateInsertButton: () => void;
5
+ clearInsertButton: () => void;
6
+ onTableMouseMove: (event: MouseEvent) => void;
7
+ scheduleTableHide: () => void;
8
+ closeBlockMenu: () => void;
9
+ closeInsertMenu: () => void;
10
+ isBlockMenuVisible: () => boolean;
11
+ isInsertMenuVisible: () => boolean;
12
+ }
13
+ export declare function useEditorEvents(options: UseEditorEventsOptions): {
14
+ onMove: (e: MouseEvent) => void;
15
+ onLeave: (e: MouseEvent) => void;
16
+ onEditorMouseDown: () => void;
17
+ onDocMouseUp: () => void;
18
+ onOverlayEnter: () => void;
19
+ onOverlayLeave: () => void;
20
+ onKeyDown: (e: KeyboardEvent) => void;
21
+ setHasSelection: (value: boolean) => void;
22
+ };
@@ -0,0 +1,28 @@
1
+ import { ComputedRef, Ref } from 'vue';
2
+ import { EmbedViewAttrs, EmbedViewMode, EmbedFileType } from '../extensions/EmbedView';
3
+ import { UrlMetadata } from '../utils/embedView/metadata';
4
+ export interface UseEmbedViewOptions {
5
+ getAttrs: () => EmbedViewAttrs;
6
+ updateAttrs: (attrs: Partial<EmbedViewAttrs>) => void;
7
+ replaceWithText?: () => void;
8
+ }
9
+ export interface UseEmbedViewResult {
10
+ fileType: ComputedRef<EmbedFileType>;
11
+ currentView: ComputedRef<EmbedViewMode>;
12
+ metadata: Ref<UrlMetadata | null>;
13
+ metadataLoading: Ref<boolean>;
14
+ loadMetadataIfNeeded: () => void;
15
+ mdHtml: Ref<string | null>;
16
+ mdLoading: Ref<boolean>;
17
+ mdError: Ref<string | null>;
18
+ loadMdIfNeeded: () => void;
19
+ setView: (view: EmbedViewMode) => void;
20
+ copyLink: () => Promise<void>;
21
+ download: () => void;
22
+ openInNewTab: () => void;
23
+ removeLink: () => void;
24
+ toggleFullscreen: (open: boolean) => void;
25
+ fullscreen: Ref<boolean>;
26
+ copyTip: Ref<boolean>;
27
+ }
28
+ export declare function useEmbedView(options: UseEmbedViewOptions): UseEmbedViewResult;
@@ -0,0 +1,28 @@
1
+ import { DEFAULT_ATTACHMENT_ACCEPT, defaultAttachmentUpload, FileUploadHandler, FileUploadResult } from '../utils/attachmentUpload';
2
+ export declare const IMAGE_FILE_ACCEPT = "image/*,.png,.jpg,.jpeg,.gif,.webp,.bmp,.svg,.avif";
3
+ export { DEFAULT_ATTACHMENT_ACCEPT, defaultAttachmentUpload, type FileUploadHandler, type FileUploadResult, };
4
+ export interface ImageFilePayload {
5
+ src: string;
6
+ alt: string;
7
+ }
8
+ export interface UseImageFileUploadOptions {
9
+ onBeforeSelect?: () => void;
10
+ onInsert: (payload: ImageFilePayload) => void;
11
+ }
12
+ export interface UseDocFileUploadOptions {
13
+ onBeforeSelect?: () => void;
14
+ onInsert: (payload: FileUploadResult) => void;
15
+ uploadHandler?: FileUploadHandler;
16
+ }
17
+ export declare function isImageFile(file: File): boolean;
18
+ export declare function readFileAsDataUrl(file: File): Promise<string | null>;
19
+ export declare function useImageFileUpload(options: UseImageFileUploadOptions): {
20
+ imageAccept: string;
21
+ onImageFileClick: (event: MouseEvent) => void;
22
+ onImageFileChange: (event: Event) => Promise<void>;
23
+ };
24
+ export declare function useDocFileUpload(options: UseDocFileUploadOptions): {
25
+ fileAccept: string;
26
+ onDocFileClick: (event: MouseEvent) => void;
27
+ onDocFileChange: (event: Event) => Promise<void>;
28
+ };
@@ -0,0 +1,19 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ import { Extension } from '@tiptap/core';
4
+ import { DecorationSet } from 'prosemirror-view';
5
+ import { PluginKey } from 'prosemirror-state';
6
+ interface CollapseState {
7
+ collapsed: Set<number>;
8
+ decorations: DecorationSet;
9
+ }
10
+ export declare const COLLAPSE_KEY: PluginKey<CollapseState>;
11
+ export declare function useHeadingCollapse(): {
12
+ extension: Extension<any, any>;
13
+ bind: (editor: Ref<Editor | undefined>, getCurrentBlockTag: () => string, getCurrentBlockPMPos: () => number | null) => {
14
+ isHeadingBlock: import('vue').ComputedRef<boolean>;
15
+ isCurrentCollapsed: import('vue').ComputedRef<boolean>;
16
+ onCollapseClick: () => void;
17
+ };
18
+ };
19
+ export {};
@@ -0,0 +1,7 @@
1
+ export declare function useHoverMenu(delay?: number): {
2
+ isOpen: import('vue').Ref<boolean, boolean>;
3
+ open: () => void;
4
+ close: () => void;
5
+ scheduleClose: () => void;
6
+ clearCloseTimer: () => void;
7
+ };
@@ -0,0 +1,7 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ export declare function useInsertButton(_editorRef: Ref<HTMLElement | null>, _editor: Ref<Editor | undefined>, getCurrentBlockEl: () => Element | null): {
4
+ isEmptyParagraph: Ref<boolean, boolean>;
5
+ updateFromCurrentBlock: () => void;
6
+ clear: () => void;
7
+ };
@@ -0,0 +1,17 @@
1
+ import { MenuPlacement } from './useMenuPosition';
2
+ export declare function useInsertMenu(getCurrentBlockPMPos: () => number | null, getAnchorRect: () => DOMRect | null, beforeOpen: () => void): {
3
+ visible: import('vue').Ref<boolean, boolean>;
4
+ top: import('vue').Ref<number, number>;
5
+ left: import('vue').Ref<number, number>;
6
+ placement: import('vue').Ref<MenuPlacement, MenuPlacement>;
7
+ targetPos: import('vue').Ref<number | null, number | null>;
8
+ openFromButton: () => void;
9
+ openFromSlash: (blockPos: number, rect: DOMRect) => void;
10
+ onButtonEnter: () => void;
11
+ onButtonLeave: (e: MouseEvent) => void;
12
+ onMenuEnter: () => void;
13
+ onMenuLeave: () => void;
14
+ close: () => void;
15
+ scheduleClose: () => void;
16
+ clearHideTimer: () => void;
17
+ };
@@ -0,0 +1,3 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ export declare function useLinkHover(editorRef: Ref<Editor | undefined>, onShow: (href: string, text: string, rect: DOMRect) => void, onHide: () => void): void;
@@ -0,0 +1,32 @@
1
+ import { Editor } from '@tiptap/vue-3';
2
+ import { EditorState } from 'prosemirror-state';
3
+ interface LinkRange {
4
+ from: number;
5
+ to: number;
6
+ }
7
+ export interface ExclusiveLinkBlock extends LinkRange {
8
+ text: string;
9
+ }
10
+ /**
11
+ * 在文档中找到 href 匹配的第一个"连续" text node 组的范围。
12
+ * 连续:相邻节点紧挨着(positions[i].from === positions[i-1].to)。
13
+ * 返回 null 表示未找到。
14
+ */
15
+ export declare function findLinkRange(state: EditorState, href: string): LinkRange | null;
16
+ export declare function findExclusiveLinkBlock(state: EditorState, href: string): ExclusiveLinkBlock | null;
17
+ /**
18
+ * 将 href 对应链接的第一个连续组文字替换为 newText,保留 link mark。
19
+ * 返回是否成功找到并替换。
20
+ */
21
+ export declare function replaceLinkText(editor: Editor, href: string, newText: string): boolean;
22
+ /**
23
+ * 取消链接:移除 link mark,保留 displayText 作为纯文本。
24
+ * displayText 应传入当前显示的链接文字(而非 href),以保留用户看到的内容。
25
+ */
26
+ export declare function unlinkText(editor: Editor, href: string, displayText: string): boolean;
27
+ /**
28
+ * 更新链接 href:在文档中找到该链接范围,用新 href 替换 link mark 属性。
29
+ * 比 chain().setLink() 更精确——不依赖当前编辑器选区。
30
+ */
31
+ export declare function updateLinkHref(editor: Editor, oldHref: string, newHref: string): boolean;
32
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Editor } from '@tiptap/vue-3';
2
+ export type MarkdownEmit = {
3
+ (event: 'update:markdown', md: string): void;
4
+ };
5
+ export declare function useMarkdownSync(getEditor: () => Editor | undefined, emit: MarkdownEmit, delay?: number): {
6
+ isSettingContent: import('vue').Ref<boolean, boolean>;
7
+ scheduleMarkdownEmit: (html: string) => void;
8
+ getHtml: () => string;
9
+ getMarkdown: () => string;
10
+ setMarkdown: (md: string) => void;
11
+ setHtml: (html: string) => void;
12
+ };
@@ -0,0 +1,38 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ export type MathNodeKind = 'inline' | 'block';
4
+ export interface MathNode {
5
+ attrs: {
6
+ latex: string;
7
+ };
8
+ }
9
+ export declare function useMath(editor: Ref<Editor | undefined>): {
10
+ visible: Ref<boolean, boolean>;
11
+ anchorRect: Ref<{
12
+ height: number;
13
+ width: number;
14
+ x: number;
15
+ y: number;
16
+ readonly bottom: number;
17
+ readonly left: number;
18
+ readonly right: number;
19
+ readonly top: number;
20
+ toJSON: () => any;
21
+ } | null, DOMRect | {
22
+ height: number;
23
+ width: number;
24
+ x: number;
25
+ y: number;
26
+ readonly bottom: number;
27
+ readonly left: number;
28
+ readonly right: number;
29
+ readonly top: number;
30
+ toJSON: () => any;
31
+ } | null>;
32
+ initialLatex: Ref<string, string>;
33
+ openForEdit: (node: MathNode, pos: number, nodeKind?: MathNodeKind) => void;
34
+ openForInsert: (insertPos: number, rect?: DOMRect | null, nodeKind?: MathNodeKind) => void;
35
+ confirm: (latex: string) => void;
36
+ close: () => void;
37
+ rectAtPos: (pos: number) => DOMRect | null;
38
+ };
@@ -0,0 +1,20 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ import { MentionAttrs } from '../extensions/Mention';
4
+ export interface MentionAnchor extends MentionAttrs {
5
+ from: number;
6
+ to: number;
7
+ }
8
+ export interface MentionTriggerPayload {
9
+ query: string;
10
+ rect: DOMRect;
11
+ }
12
+ export interface UseMentionOptions {
13
+ onTrigger?: (payload: MentionTriggerPayload) => void;
14
+ onCancel?: () => void;
15
+ }
16
+ export declare function useMention(editorRef: Ref<Editor | undefined>, options?: UseMentionOptions): {
17
+ insertMention: (attrs: MentionAttrs) => boolean;
18
+ getMentions: () => MentionAnchor[];
19
+ applyMentions: (mentions: MentionAnchor[]) => boolean;
20
+ };
@@ -0,0 +1,13 @@
1
+ export type MenuPlacement = 'left' | 'right' | 'below' | 'above';
2
+ export interface MenuAnchor {
3
+ top: number;
4
+ left: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export interface MenuPosition {
9
+ top: number;
10
+ left: number;
11
+ placement: MenuPlacement;
12
+ }
13
+ export declare function calcMenuPosition(anchor: MenuAnchor, menuWidth: number, preferredPlacement: MenuPlacement, gap?: number, menuHeight?: number): MenuPosition;
@@ -0,0 +1,27 @@
1
+ import { CSSProperties, Ref, WatchSource } from 'vue';
2
+ import { MenuPlacement } from './useMenuPosition';
3
+ export declare const MENU_PANEL_WIDTH = 224;
4
+ export declare const MENU_PANEL_GAP = 4;
5
+ export declare const MENU_PANEL_EDGE = 8;
6
+ export declare const MENU_ITEM_HEIGHT = 32;
7
+ export declare const MENU_CLOSE_DELAY = 120;
8
+ export declare function getMenuEnterTranslate(placement: MenuPlacement): string;
9
+ export interface MenuSidePanelOptions {
10
+ visible: WatchSource<boolean>;
11
+ rootSelector: string;
12
+ estimatedHeight: () => number;
13
+ fallbackTop: () => number;
14
+ fallbackLeft: () => number;
15
+ closeDelay?: number;
16
+ }
17
+ export declare function useMenuSidePanel<Id extends string>(options: MenuSidePanelOptions): {
18
+ rootId: Ref<Id | null, Id | null>;
19
+ hovered: Ref<boolean, boolean>;
20
+ style: import('vue').ComputedRef<CSSProperties>;
21
+ open: (id: Id, event: MouseEvent) => void;
22
+ close: () => void;
23
+ scheduleClose: () => void;
24
+ clearCloseTimer: () => void;
25
+ onPanelMouseEnter: () => void;
26
+ onPanelMouseLeave: () => void;
27
+ };
@@ -0,0 +1,12 @@
1
+ export declare function useNodeViewCommentAttrs(getAttrs: () => Record<string, unknown>): {
2
+ commentAttrs: import('vue').ComputedRef<{
3
+ 'data-comment-ids'?: undefined;
4
+ 'data-comment-count'?: undefined;
5
+ } | {
6
+ 'data-comment-ids': string;
7
+ 'data-comment-count': string | undefined;
8
+ }>;
9
+ commentClass: import('vue').ComputedRef<{
10
+ 'pagely-comment-block': boolean;
11
+ }>;
12
+ };
@@ -0,0 +1,17 @@
1
+ import { Ref } from 'vue';
2
+ import { Content, Extension } from '@tiptap/core';
3
+ import { ExtensionProfile } from '../config/extensionProfiles';
4
+ import { FileUploadHandler } from '../utils/attachmentUpload';
5
+ export interface UsePagelyEditorOptions {
6
+ profile: ExtensionProfile;
7
+ initialContent: Content;
8
+ headingCollapseExtension?: Extension;
9
+ isSettingContent: Ref<boolean>;
10
+ editable?: boolean;
11
+ onHtmlUpdate?: (html: string) => void;
12
+ onSelectionUpdate?: () => void;
13
+ onOpenMathPopover?: (node: unknown, pos: number, kind: 'inline' | 'block') => void;
14
+ onOpenSlashInsert?: (blockPos: number, rect: DOMRect) => void;
15
+ fileUploadHandler?: FileUploadHandler;
16
+ }
17
+ export declare function usePagelyEditor(options: UsePagelyEditorOptions): import('vue').ShallowRef<import('@tiptap/vue-3').Editor | undefined, import('@tiptap/vue-3').Editor | undefined>;
@@ -0,0 +1,3 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ export declare function useSelectionToolbar(editorRef: Ref<Editor | undefined>, onShow: (rect: DOMRect) => void, onHide: () => void): void;
@@ -0,0 +1,21 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ import { CellOpKind } from '../config/insertMenu';
4
+ export interface CellBounds {
5
+ top: number;
6
+ left: number;
7
+ width: number;
8
+ height: number;
9
+ }
10
+ export declare function useTableCellOps(editor: Ref<Editor | undefined>, currentTable: Ref<HTMLElement | null>, currentCell: Ref<HTMLElement | null>, hoveredCellBounds: Ref<CellBounds | null>, refreshDots: (table: HTMLElement) => void, hide: () => void): {
11
+ cellOps: Record<CellOpKind, () => void>;
12
+ focusCell: (cell: HTMLElement) => void;
13
+ focusFirstCell: () => void;
14
+ focusLastRowCell: () => void;
15
+ focusLastColCell: () => void;
16
+ focusHoveredCell: () => void;
17
+ insertRowAt: (index: number) => void;
18
+ insertColAt: (index: number) => void;
19
+ refreshCurrentCellFromSelection: () => void;
20
+ getCurrentCellRootPMPos: () => number | null;
21
+ };
@@ -0,0 +1,60 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ import { Node as ProseMirrorNode } from 'prosemirror-model';
4
+ import { TableAlign } from '../utils/tableAlign';
5
+ export interface InsertDot {
6
+ pos: number;
7
+ index: number;
8
+ }
9
+ export interface ColAlignDot {
10
+ pos: number;
11
+ y: number;
12
+ colIndex: number;
13
+ align: TableAlign;
14
+ }
15
+ export declare function getDirectRows(table: HTMLElement): HTMLElement[];
16
+ export declare function getDirectCells(row: Element | null | undefined): HTMLElement[];
17
+ export declare function getFirstDirectCell(row: Element | null | undefined): HTMLElement | null;
18
+ export declare function useTableDots(editor: Ref<Editor | undefined>): {
19
+ tableBounds: {
20
+ top: number;
21
+ left: number;
22
+ width: number;
23
+ height: number;
24
+ };
25
+ rowDots: Ref<{
26
+ pos: number;
27
+ index: number;
28
+ }[], InsertDot[] | {
29
+ pos: number;
30
+ index: number;
31
+ }[]>;
32
+ colDots: Ref<{
33
+ pos: number;
34
+ index: number;
35
+ }[], InsertDot[] | {
36
+ pos: number;
37
+ index: number;
38
+ }[]>;
39
+ colAlignDots: Ref<{
40
+ pos: number;
41
+ y: number;
42
+ colIndex: number;
43
+ align: TableAlign;
44
+ }[], ColAlignDot[] | {
45
+ pos: number;
46
+ y: number;
47
+ colIndex: number;
48
+ align: TableAlign;
49
+ }[]>;
50
+ hasHeaderRow: Ref<boolean, boolean>;
51
+ hasHeaderCol: Ref<boolean, boolean>;
52
+ findPmTableState: (table: HTMLElement) => {
53
+ node: ProseMirrorNode;
54
+ pos: number;
55
+ } | null;
56
+ refreshDots: (table: HTMLElement) => void;
57
+ refreshHeaderState: (table: HTMLElement) => void;
58
+ refreshColumnAlignDots: (table: HTMLElement) => void;
59
+ clearDots: () => void;
60
+ };
@@ -0,0 +1,72 @@
1
+ import { Ref } from 'vue';
2
+ import { Editor } from '@tiptap/vue-3';
3
+ import { TableAlign } from '../utils/tableAlign';
4
+ import { CellBounds } from './useTableCellOps';
5
+ import { ColAlignDot, InsertDot } from './useTableDots';
6
+ export type { CellBounds, ColAlignDot, InsertDot };
7
+ export declare function useTableTools(_editorRef: Ref<HTMLElement | null>, editor: Ref<Editor | undefined>): {
8
+ tableVisible: Ref<boolean, boolean>;
9
+ tableBounds: {
10
+ top: number;
11
+ left: number;
12
+ width: number;
13
+ height: number;
14
+ };
15
+ rowDots: Ref<{
16
+ pos: number;
17
+ index: number;
18
+ }[], InsertDot[] | {
19
+ pos: number;
20
+ index: number;
21
+ }[]>;
22
+ colDots: Ref<{
23
+ pos: number;
24
+ index: number;
25
+ }[], InsertDot[] | {
26
+ pos: number;
27
+ index: number;
28
+ }[]>;
29
+ colAlignDots: Ref<{
30
+ pos: number;
31
+ y: number;
32
+ colIndex: number;
33
+ align: TableAlign;
34
+ }[], ColAlignDot[] | {
35
+ pos: number;
36
+ y: number;
37
+ colIndex: number;
38
+ align: TableAlign;
39
+ }[]>;
40
+ hoveredCellBounds: Ref<{
41
+ top: number;
42
+ left: number;
43
+ width: number;
44
+ height: number;
45
+ } | null, CellBounds | {
46
+ top: number;
47
+ left: number;
48
+ width: number;
49
+ height: number;
50
+ } | null>;
51
+ hasHeaderRow: Ref<boolean, boolean>;
52
+ hasHeaderCol: Ref<boolean, boolean>;
53
+ onTableMouseMove: (e: MouseEvent) => void;
54
+ onTableSelectionUpdate: () => void;
55
+ keepAlive: () => void;
56
+ scheduleHide: () => void;
57
+ insertRowAt: (index: number) => void;
58
+ insertColAt: (index: number) => void;
59
+ cellOps: Record<import('..').CellOpKind, () => void>;
60
+ tableAddRowAfter: () => void;
61
+ tableAddColumnAfter: () => void;
62
+ tableToggleHeaderRow: () => void;
63
+ tableToggleHeaderColumn: () => void;
64
+ setColumnAlign: (align: TableAlign, colIndex?: number) => void;
65
+ tableDeleteTable: () => void;
66
+ tableCopyTable: () => void;
67
+ tableCutTable: () => void;
68
+ getCurrentTableRootPMPos: () => number | null;
69
+ tableFocusFirstCell: () => void;
70
+ focusHoveredCell: () => void;
71
+ getCurrentCellRootPMPos: () => number | null;
72
+ };
@@ -0,0 +1,39 @@
1
+ import { MenuChain } from '../../types/menuCommands';
2
+ import { MenuItemDef } from './items';
3
+ export type { ItemId, MenuItemDef, BlockOpId } from './items';
4
+ export type { SectionId, SectionDef } from './sections';
5
+ export type { ProfileId, ProfileDef } from './profiles';
6
+ export type { BlockDisplay } from './tagMapping';
7
+ export { MENU_ITEMS } from './items';
8
+ export { MENU_SECTIONS } from './sections';
9
+ export { MENU_PROFILES } from './profiles';
10
+ export { BLOCK_DISPLAY, BLOCK_TAG_TO_PROFILE } from './tagMapping';
11
+ export interface MenuSectionDef {
12
+ label?: string;
13
+ style?: 'tiles' | 'list';
14
+ items: MenuItemDef[];
15
+ }
16
+ export interface BlockConfig {
17
+ label: string;
18
+ icon: import('vue').Component;
19
+ pillVariant: 'text' | 'table' | 'minimal';
20
+ sections: MenuSectionDef[];
21
+ /** Which element's rect to use for overlay positioning (default: blockEl) */
22
+ getRectEl?: (blockEl: Element) => Element;
23
+ /** Which element to pass to posAtDOM (default: blockEl) */
24
+ getPMDomTarget?: (blockEl: Element) => Element;
25
+ /** How to apply a type-conversion command (default: no-op) */
26
+ applyConvert?: (chain: MenuChain, id: string) => void;
27
+ /** tile 高亮 ID(静态,默认用 tag 本身) */
28
+ currentTypeId?: string;
29
+ /** tile 高亮 ID(动态,优先级低于 currentTypeId,用于依赖 DOM 的情况) */
30
+ getCurrentTypeId?: (blockEl: Element) => string;
31
+ /**
32
+ * 包裹型节点:内部仍有独立的文本类型(P / H1-H6 等)。
33
+ * 为 true 时,tile 菜单同时高亮本节点类型 + 内部文本类型。
34
+ * 未标记的块类型之间互斥(同一时刻只高亮一个 tile)。
35
+ */
36
+ isWrapper?: true;
37
+ }
38
+ export declare function getBlockConfig(tag: string): BlockConfig;
39
+ export declare const BLOCK_CONFIGS: Record<string, BlockConfig>;
@@ -0,0 +1,26 @@
1
+ import { Component } from 'vue';
2
+ export type ItemId = 'P' | 'H1' | 'H2' | 'H3' | 'H4' | 'H5' | 'H6' | 'UL' | 'OL' | 'LI_TASK' | 'PRE' | 'BLOCKQUOTE' | 'COPY_BLOCK' | 'DELETE_BLOCK' | 'CUT_BLOCK' | 'COPY_CODE' | 'DELETE_CODE_BLOCK' | 'COPY_CANVAS_CODE' | 'COPY_CANVAS_IMAGE' | 'CUT_TABLE' | 'COPY_TABLE' | 'TOGGLE_TABLE_HEADER_ROW' | 'TOGGLE_TABLE_HEADER_COL' | 'DELETE_TABLE' | 'CANVAS' | 'MERMAID' | 'INDENT_INC' | 'INDENT_DEC' | 'SUBMENU_INDENT_LIST' | 'COLOR';
3
+ /** Block-level operations dispatched via useBlockOps.applyBlockOp. */
4
+ export type BlockOpId = 'copyBlock' | 'copyCode' | 'copyCanvasCode' | 'copyCanvasImage' | 'copyTable' | 'cutTable' | 'cutBlock' | 'deleteBlock' | 'deleteCodeBlock' | 'deleteTable' | 'toggleTableHeaderRow' | 'toggleTableHeaderColumn';
5
+ export interface MenuItemDef {
6
+ id: string;
7
+ label: string;
8
+ icon: Component;
9
+ shortcut?: string;
10
+ danger?: boolean;
11
+ /** 悬停预览描述文字(hover 时右侧弹出面板中显示) */
12
+ description?: string;
13
+ /** 行为类别:缺省为类型转换 */
14
+ action?: 'indent' | 'op';
15
+ /** 缩进方向(action === 'indent') */
16
+ indentDir?: 'inc' | 'dec';
17
+ /** 块级操作(action === 'op') */
18
+ op?: BlockOpId;
19
+ /** Render a switch indicator for active/inactive operation rows. */
20
+ toggle?: boolean;
21
+ /** 二级菜单项 ID(与 panel 互斥) */
22
+ children?: ItemId[];
23
+ /** 二级面板类型:渲染自定义面板而非扁平的 children 列表(与 children 互斥) */
24
+ panel?: 'color';
25
+ }
26
+ export declare const MENU_ITEMS: Record<ItemId, MenuItemDef>;
@@ -0,0 +1,13 @@
1
+ import { BlockConvertId } from '../../composables/useBlockConvert';
2
+ import { SectionId } from './sections';
3
+ export type ProfileId = 'TEXT_LIKE' | 'HEADING' | 'BLOCKQUOTE' | 'TASK_ITEM' | 'LI' | 'PRE' | 'TABLE' | 'TABLE_CELL' | 'MINIMAL' | 'MERMAID' | 'CANVAS' | 'IMAGE' | 'EMBED_VIEW';
4
+ export interface ProfileDef {
5
+ sections: SectionId[];
6
+ getRectEl?: (blockEl: Element) => Element;
7
+ getPMDomTarget?: (blockEl: Element) => Element;
8
+ convert?: BlockConvertId;
9
+ currentTypeId?: string;
10
+ getCurrentTypeId?: (blockEl: Element) => string;
11
+ isWrapper?: true;
12
+ }
13
+ export declare const MENU_PROFILES: Record<ProfileId, ProfileDef>;
@@ -0,0 +1,8 @@
1
+ import { ItemId } from './items';
2
+ export type SectionId = 'CONVERT_TILES' | 'DRAW' | 'OPS' | 'CODE_OPS' | 'TABLE_OPS' | 'INDENT_LIST' | 'COLOR_SECTION' | 'CANVAS_OPS' | 'IMAGE_OPS' | 'EMBED_VIEW_OPS';
3
+ export interface SectionDef {
4
+ label?: string;
5
+ style?: 'tiles' | 'list';
6
+ items: ItemId[];
7
+ }
8
+ export declare const MENU_SECTIONS: Record<SectionId, SectionDef>;
@@ -0,0 +1,9 @@
1
+ import { Component } from 'vue';
2
+ import { ProfileId } from './profiles';
3
+ export interface BlockDisplay {
4
+ label: string;
5
+ icon: Component;
6
+ pillVariant: 'text' | 'table' | 'minimal';
7
+ }
8
+ export declare const BLOCK_TAG_TO_PROFILE: Record<string, ProfileId>;
9
+ export declare const BLOCK_DISPLAY: Record<string, BlockDisplay>;
@@ -0,0 +1 @@
1
+ export * from './blockMenu';
@@ -0,0 +1,3 @@
1
+ export type ExtensionProfile = 'edit' | 'view' | 'comment';
2
+ export declare const EXTENSION_PROFILES: Record<string, ExtensionProfile[]>;
3
+ export declare function shouldLoad(extName: string, profile: ExtensionProfile): boolean;
@@ -0,0 +1,2 @@
1
+ import { MenuChain } from '../../types/menuCommands';
2
+ export declare const INSERT_BLOCK_CMDS: Record<string, (chain: MenuChain) => void>;
@@ -0,0 +1,22 @@
1
+ import { Component } from 'vue';
2
+ import { InsertItemDef } from './items';
3
+ import { ResolvedInsertSectionDef } from './sections';
4
+ export type CellOpKind = 'rowBefore' | 'rowAfter' | 'colBefore' | 'colAfter' | 'delRow' | 'delCol';
5
+ export interface CellOpItemDef {
6
+ id: CellOpKind;
7
+ label: string;
8
+ icon: Component;
9
+ danger?: boolean;
10
+ kind: 'cell-op';
11
+ }
12
+ export type InsertMenuItemDef = InsertItemDef | CellOpItemDef;
13
+ export interface ResolvedInsertMenuSectionDef {
14
+ label: string;
15
+ style: 'tiles' | 'list';
16
+ items: InsertMenuItemDef[];
17
+ }
18
+ export declare const CELL_OP_ITEMS: Record<CellOpKind, CellOpItemDef>;
19
+ export declare const CELL_OP_SECTIONS: ResolvedInsertMenuSectionDef[];
20
+ export declare const RESOLVED_INSERT_SECTIONS_CELL_WITH_OPS: ResolvedInsertMenuSectionDef[];
21
+ export declare function isCellOpItem(item: InsertMenuItemDef): item is CellOpItemDef;
22
+ export declare function asInsertMenuSections(sections: ResolvedInsertSectionDef[]): ResolvedInsertMenuSectionDef[];
@@ -0,0 +1,16 @@
1
+ import { InsertItemId } from './items';
2
+ import { MenuChain } from '../../types/menuCommands';
3
+ import { EmbedViewMode } from '../../extensions/EmbedView';
4
+ export interface InsertCtx {
5
+ pos?: number;
6
+ rows?: number;
7
+ cols?: number;
8
+ src?: string;
9
+ alt?: string | null;
10
+ title?: string | null;
11
+ label?: string;
12
+ text?: string;
13
+ href?: string;
14
+ view?: EmbedViewMode;
15
+ }
16
+ export declare const INSERT_CMDS: Record<InsertItemId, (chain: MenuChain, ctx?: InsertCtx) => void>;
@@ -0,0 +1,10 @@
1
+ export type { InsertItemDef, InsertItemId, InsertPickerKind } from './items';
2
+ export type { InsertSectionDef, ResolvedInsertSectionDef } from './sections';
3
+ export type { InsertCtx } from './commands';
4
+ export type { MenuChain } from '../../types/menuCommands';
5
+ export type { CellOpItemDef, CellOpKind, InsertMenuItemDef, ResolvedInsertMenuSectionDef } from './cellOps';
6
+ export { INSERT_ITEMS } from './items';
7
+ export { INSERT_SECTIONS, INSERT_SECTIONS_CELL, RESOLVED_INSERT_SECTIONS, RESOLVED_INSERT_SECTIONS_CELL } from './sections';
8
+ export { INSERT_CMDS } from './commands';
9
+ export { INSERT_BLOCK_CMDS } from './blockCommands';
10
+ export { CELL_OP_ITEMS, CELL_OP_SECTIONS, RESOLVED_INSERT_SECTIONS_CELL_WITH_OPS, asInsertMenuSections, isCellOpItem, } from './cellOps';