{"library":"prosemirror-resizable-view","title":"ProseMirror Resizable View","description":"The `prosemirror-resizable-view` package provides a specialized `NodeView` implementation for ProseMirror that enables users to resize custom nodes directly within the editor interface. It is an integral part of the broader Remirror ecosystem and currently aligns with Remirror's stable version 3.0.0. This package itself is at version 3.0.0, benefiting from the active development cadence of the Remirror project, which includes regular patch releases for bug fixes and dependency updates. Its primary differentiator lies in abstracting the complexities of implementing resizable DOM elements within a ProseMirror `NodeView`, offering a convenient base class that handles drag events and dimension management. This significantly simplifies the development process for integrating dynamic resize functionality for various content types like images, video embeds, or custom block components. The package comes with comprehensive TypeScript type definitions, enhancing developer experience and code safety.","language":"javascript","status":"active","last_verified":"Sun Apr 19","install":{"commands":["npm install prosemirror-resizable-view"],"cli":null},"imports":["import { ResizableNodeView } from 'prosemirror-resizable-view';","import { Node as ProsemirrorNode } from 'prosemirror-model';","import { EditorView, NodeView } from 'prosemirror-view';","import { EditorView } from 'prosemirror-view';"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import { ResizableNodeView } from 'prosemirror-resizable-view';\nimport { Node as ProsemirrorNode, Schema } from 'prosemirror-model';\nimport { EditorView, NodeView } from 'prosemirror-view';\nimport { EditorState } from 'prosemirror-state';\nimport { baseKeymap } from 'prosemirror-commands';\nimport { keymap } from 'prosemirror-keymap';\n\n// 1. Define a basic schema with an 'image' node that can have width/height attributes\nconst mySchema = new Schema({\n  nodes: {\n    doc: { content: 'block+' },\n    paragraph: { content: 'inline*', group: 'block' },\n    image: {\n      inline: false,\n      attrs: {\n        src: { default: '' },\n        alt: { default: null },\n        title: { default: null },\n        width: { default: null },\n        height: { default: null },\n      },\n      group: 'block',\n      parseDOM: [{\n        tag: 'img[src]',\n        getAttrs(dom) {\n          if (typeof dom === 'string') return {};\n          return {\n            src: dom.getAttribute('src'),\n            alt: dom.getAttribute('alt'),\n            title: dom.getAttribute('title'),\n            width: dom.getAttribute('width'),\n            height: dom.getAttribute('height'),\n          };\n        },\n      }],\n      toDOM(node) {\n        return [\n          'img',\n          {\n            src: node.attrs.src,\n            alt: node.attrs.alt,\n            title: node.attrs.title,\n            width: node.attrs.width, // Render initial width\n            height: node.attrs.height, // Render initial height\n          },\n        ];\n      },\n    },\n    text: { inline: true, group: 'inline' },\n  },\n  marks: {},\n});\n\n// 2. Helper function to create the actual DOM element for the image\nconst createInnerImage = ({ node }: { node: ProsemirrorNode }) => {\n  const inner = document.createElement('img');\n  inner.setAttribute('src', node.attrs.src);\n  if (node.attrs.alt) inner.setAttribute('alt', node.attrs.alt);\n  if (node.attrs.title) inner.setAttribute('title', node.attrs.title);\n  inner.style.width = node.attrs.width ? `${node.attrs.width}px` : '100%';\n  inner.style.height = node.attrs.height ? `${node.attrs.height}px` : 'auto';\n  inner.style.minWidth = '50px';\n  inner.style.objectFit = 'contain';\n  return inner;\n};\n\n// 3. Extend ResizableNodeView to create a custom resizable image view\nexport class ResizableImageView extends ResizableNodeView implements NodeView {\n  constructor(node: ProsemirrorNode, view: EditorView, getPos: () => number) {\n    super({\n      node,\n      view,\n      getPos,\n      createElement: createInnerImage,\n      // Optional: Set aspectRatio to 'lock' to maintain aspect ratio, or 'free'.\n      // aspectRatio: 'lock',\n      updateSize: (width, height) => {\n        // This callback is crucial: dispatch a transaction to update the node's attributes\n        const tr = view.state.tr.setNodeMarkup(getPos(), undefined, {\n          ...node.attrs,\n          width,\n          height,\n        });\n        view.dispatch(tr);\n      },\n    });\n  }\n}\n\n// 4. Set up the ProseMirror Editor\nconst editorDiv = document.createElement('div');\neditorDiv.id = 'editor';\ndocument.body.appendChild(editorDiv);\n\nconst state = EditorState.create({\n  schema: mySchema,\n  doc: mySchema.nodeFromJSON({\n    type: 'doc',\n    content: [\n      {\n        type: 'paragraph',\n        content: [{ type: 'text', text: 'Drag the handles to resize the image:' }],\n      },\n      {\n        type: 'image',\n        attrs: { src: 'https://via.placeholder.com/250x180', width: 250, height: 180 },\n      },\n      {\n        type: 'paragraph',\n        content: [{ type: 'text', text: 'This is some text below the resizable image.' }],\n      },\n    ],\n  }),\n  plugins: [keymap(baseKeymap)],\n});\n\nconst view = new EditorView(editorDiv, {\n  state,\n  nodeViews: {\n    image(node, view, getPos) {\n      return new ResizableImageView(node, view, getPos);\n    },\n  },\n});\n\n// Expose view for debugging in browser console\n(window as any).view = view;\n","lang":"typescript","description":"This quickstart demonstrates how to create a basic ProseMirror editor with a custom `image` node, then renders this node using `ResizableImageView` to allow users to resize images within the editor. It includes schema definition, `ResizableNodeView` extension, and editor setup.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":null}