import type { NodeType } from '@tiptap/pm/model' import { mergeAttributes, Node, ReactNodeViewRenderer } from '@tiptap/react' import { MediaGalleryPlaceholderNode as MediaGalleryPlaceholderNodeComponent } from './media-gallery-placeholder-node' export interface MediaGalleryPlaceholderNodeOptions { type?: string | NodeType | undefined accept?: string HTMLAttributes: Record } declare module '@tiptap/react' { interface Commands { mediaGalleryPlaceholder: { setMediaGalleryPlaceholderNode: (options?: MediaGalleryPlaceholderNodeOptions) => ReturnType } } } export const MediaGalleryPlaceholderNode = Node.create({ name: 'mediaGalleryPlaceholder', group: 'block', draggable: true, selectable: true, atom: true, addOptions() { return { type: 'image', accept: 'image/*', HTMLAttributes: {} } }, addAttributes() { return { accept: { default: this.options.accept } } }, parseHTML() { return [{ tag: 'div[data-type="media-gallery-placeholder"]' }] }, renderHTML({ HTMLAttributes }) { return ['div', mergeAttributes({ 'data-type': 'media-gallery-placeholder' }, HTMLAttributes)] }, addNodeView() { return ReactNodeViewRenderer(MediaGalleryPlaceholderNodeComponent) }, addCommands() { return { setMediaGalleryPlaceholderNode: (options) => ({ commands }) => { return commands.insertContent({ type: this.name, attrs: options }) } } }, addKeyboardShortcuts() { return { Enter: ({ editor }) => { const { selection } = editor.state const { nodeAfter } = selection.$from if ( nodeAfter && nodeAfter.type.name === 'mediaGalleryPlaceholder' && editor.isActive('mediaGalleryPlaceholder') ) { const nodeEl = editor.view.nodeDOM(selection.$from.pos) if (nodeEl && nodeEl instanceof HTMLElement) { const trigger = nodeEl.querySelector('button') if (trigger && trigger instanceof HTMLElement) { trigger.click() return true } } } return false } } } }) export default MediaGalleryPlaceholderNode