neuphlo-editor 1.3.2 → 1.4.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 (74) hide show
  1. package/README.md +21 -17
  2. package/dist/react/index.cjs +57 -34
  3. package/dist/react/index.cjs.map +1 -1
  4. package/dist/react/index.d.cts +6 -1
  5. package/dist/react/index.d.ts +6 -1
  6. package/dist/react/index.js +57 -34
  7. package/dist/react/index.js.map +1 -1
  8. package/package.json +10 -4
  9. package/dist/chunk-TPFBGHW3.js +0 -1071
  10. package/dist/chunk-TPFBGHW3.js.map +0 -1
  11. package/dist/headless/components/editor-bubble-item.d.ts +0 -9
  12. package/dist/headless/components/editor-bubble-item.js +0 -29
  13. package/dist/headless/components/editor-bubble.d.ts +0 -9
  14. package/dist/headless/components/editor-bubble.js +0 -9
  15. package/dist/headless/components/editor-command-item.d.ts +0 -3
  16. package/dist/headless/components/editor-command-item.js +0 -18
  17. package/dist/headless/components/editor-command.d.ts +0 -10
  18. package/dist/headless/components/editor-command.js +0 -48
  19. package/dist/headless/components/editor.d.ts +0 -24
  20. package/dist/headless/components/editor.js +0 -13
  21. package/dist/headless/extensions/CodeBlock/CodeBlock.d.ts +0 -1
  22. package/dist/headless/extensions/CodeBlock/CodeBlock.js +0 -6
  23. package/dist/headless/extensions/CodeBlock/index.d.ts +0 -1
  24. package/dist/headless/extensions/CodeBlock/index.js +0 -1
  25. package/dist/headless/extensions/Image/Image.d.ts +0 -6
  26. package/dist/headless/extensions/Image/Image.js +0 -197
  27. package/dist/headless/extensions/ImageBlock/ImageBlock.d.ts +0 -21
  28. package/dist/headless/extensions/ImageBlock/ImageBlock.js +0 -240
  29. package/dist/headless/extensions/ImageBlock/index.d.ts +0 -2
  30. package/dist/headless/extensions/ImageBlock/index.js +0 -1
  31. package/dist/headless/extensions/Link/Link.d.ts +0 -2
  32. package/dist/headless/extensions/Link/Link.js +0 -40
  33. package/dist/headless/extensions/Link/index.d.ts +0 -1
  34. package/dist/headless/extensions/Link/index.js +0 -1
  35. package/dist/headless/extensions/extension-kit.d.ts +0 -5
  36. package/dist/headless/extensions/extension-kit.js +0 -29
  37. package/dist/headless/extensions/index.d.ts +0 -6
  38. package/dist/headless/extensions/index.js +0 -6
  39. package/dist/headless/extensions/slash-command.d.ts +0 -36
  40. package/dist/headless/extensions/slash-command.js +0 -105
  41. package/dist/headless/utils/atoms.d.ts +0 -7
  42. package/dist/headless/utils/atoms.js +0 -3
  43. package/dist/headless/utils/store.d.ts +0 -2
  44. package/dist/headless/utils/store.js +0 -4
  45. package/dist/react/Editor.d.ts +0 -27
  46. package/dist/react/Editor.js +0 -33
  47. package/dist/react/menus/ImageBlock/ImageBlockLoading.d.ts +0 -2
  48. package/dist/react/menus/ImageBlock/ImageBlockLoading.js +0 -6
  49. package/dist/react/menus/ImageBlock/ImageBlockMenu.d.ts +0 -7
  50. package/dist/react/menus/ImageBlock/ImageBlockMenu.js +0 -100
  51. package/dist/react/menus/ImageBlock/ImageBlockView.d.ts +0 -10
  52. package/dist/react/menus/ImageBlock/ImageBlockView.js +0 -44
  53. package/dist/react/menus/ImageBlock/ImageBlockWidth.d.ts +0 -6
  54. package/dist/react/menus/ImageBlock/ImageBlockWidth.js +0 -29
  55. package/dist/react/menus/ImageBlock/ImageUploader.d.ts +0 -7
  56. package/dist/react/menus/ImageBlock/ImageUploader.js +0 -63
  57. package/dist/react/menus/ImageBlock/index.d.ts +0 -4
  58. package/dist/react/menus/ImageBlock/index.js +0 -4
  59. package/dist/react/menus/ImageMenu.d.ts +0 -10
  60. package/dist/react/menus/ImageMenu.js +0 -79
  61. package/dist/react/menus/ImagePopover.d.ts +0 -8
  62. package/dist/react/menus/ImagePopover.js +0 -146
  63. package/dist/react/menus/LinkPopover.d.ts +0 -9
  64. package/dist/react/menus/LinkPopover.js +0 -113
  65. package/dist/react/menus/MenuList.d.ts +0 -10
  66. package/dist/react/menus/MenuList.js +0 -94
  67. package/dist/react/menus/SlashMenu.d.ts +0 -5
  68. package/dist/react/menus/SlashMenu.js +0 -79
  69. package/dist/react/menus/TextMenu.d.ts +0 -10
  70. package/dist/react/menus/TextMenu.js +0 -94
  71. package/dist/react/menus/bubble-menu-extensions.d.ts +0 -19
  72. package/dist/react/menus/bubble-menu-extensions.js +0 -17
  73. package/dist/react/menus/index.d.ts +0 -9
  74. package/dist/react/menus/index.js +0 -5
package/README.md CHANGED
@@ -261,43 +261,41 @@ Both the text and image bubble menus can expand with custom controls. Pass the `
261
261
 
262
262
  ```tsx
263
263
  import type { Editor } from "@tiptap/react"
264
+ import { Sparkles } from "lucide-react" // or any icon library
264
265
 
265
266
  const bubbleMenuExtras = {
266
267
  text: {
267
- align: "start", // show on the left side of the menu
268
+ align: "start", // "start" (left) or "end" (right)
268
269
  render: (editor: Editor) => (
269
270
  <button
270
271
  type="button"
271
272
  className="nph-btn nph-btn-ghost nph-btn-xs nph-btn-icon"
272
273
  onMouseDown={(e) => e.preventDefault()}
273
274
  onClick={() => {
274
- if (editor.state.selection.empty) return
275
- const note = window.prompt("Add note", "Needs review")
276
- if (!note) return
277
- const { to } = editor.state.selection
278
- editor.chain().focus().insertContentAt(to, ` [Note: ${note}]`).run()
275
+ const selection = editor.state.selection
276
+ const text = editor.state.doc.textBetween(selection.from, selection.to)
277
+ console.log("AI Action on:", text)
278
+ // Trigger your AI logic here
279
279
  }}
280
+ title="AI Assistant"
280
281
  >
281
- Add note
282
+ <Sparkles size={16} />
282
283
  </button>
283
284
  ),
284
285
  },
285
286
  image: {
286
- // Default align is "end" (right side). You can pass an array for multiple buttons.
287
+ align: "end",
287
288
  render: (editor: Editor) => (
288
289
  <button
289
290
  type="button"
290
291
  className="nph-btn nph-btn-ghost nph-btn-xs nph-btn-icon"
291
292
  onMouseDown={(e) => e.preventDefault()}
292
- onClick={() =>
293
- editor
294
- .chain()
295
- .focus()
296
- .updateAttributes("image", { align: "left" })
297
- .run()
298
- }
293
+ onClick={() => {
294
+ // Custom image action
295
+ console.log("Custom image action")
296
+ }}
299
297
  >
300
- Pin left
298
+ Custom Action
301
299
  </button>
302
300
  ),
303
301
  },
@@ -306,7 +304,13 @@ const bubbleMenuExtras = {
306
304
  <Editor bubbleMenuExtras={bubbleMenuExtras} />
307
305
  ```
308
306
 
309
- Each render callback receives the live Tiptap editor so you can check selection state, trigger commands, or early-return `null` to hide your custom control. The optional `align` flag lets you position the control on the left (`"start"`) or right (`"end"`, default) side of the bubble menu.
307
+ Each render callback receives the live Tiptap editor instance, allowing you to:
308
+ - Check the current selection state
309
+ - Read the document content
310
+ - Execute commands (e.g., `editor.chain().focus()...`)
311
+ - Conditionally render your button (return `null` to hide it)
312
+
313
+ The `align` property controls where your custom items appear in the menu relative to the default items.
310
314
 
311
315
  ## Styling
312
316
 
@@ -992,31 +992,53 @@ var handleCommandNavigation = (event) => {
992
992
  };
993
993
 
994
994
  // src/headless/extensions/extension-kit.ts
995
- var ExtensionKit = (options) => [
996
- import_starter_kit.StarterKit.configure({}),
997
- CodeBlock,
998
- Link,
999
- ImageBlock.configure({
1000
- uploadImage: options?.uploadImage
1001
- }),
1002
- import_extension_placeholder.Placeholder.configure({
1003
- placeholder: ({ node }) => {
1004
- if (node.type.name === "heading") {
1005
- return `Heading ${node.attrs.level}`;
995
+ var import_extension_collaboration = __toESM(require("@tiptap/extension-collaboration"), 1);
996
+ var import_extension_collaboration_cursor = __toESM(require("@tiptap/extension-collaboration-cursor"), 1);
997
+ var ExtensionKit = (options) => {
998
+ const extensions = [
999
+ import_starter_kit.StarterKit.configure({ codeBlock: false, link: false }),
1000
+ CodeBlock,
1001
+ Link,
1002
+ ImageBlock.configure({
1003
+ uploadImage: options?.uploadImage
1004
+ }),
1005
+ import_extension_placeholder.Placeholder.configure({
1006
+ placeholder: ({ node }) => {
1007
+ if (node.type.name === "heading") {
1008
+ return `Heading ${node.attrs.level}`;
1009
+ }
1010
+ return "Press '/' for commands";
1011
+ },
1012
+ includeChildren: true
1013
+ }),
1014
+ Command2.configure({
1015
+ suggestion: {
1016
+ char: "/",
1017
+ render: renderItems,
1018
+ allowSpaces: true,
1019
+ allowedPrefixes: null
1006
1020
  }
1007
- return "Press '/' for commands";
1008
- },
1009
- includeChildren: true
1010
- }),
1011
- Command2.configure({
1012
- suggestion: {
1013
- char: "/",
1014
- render: renderItems,
1015
- allowSpaces: true,
1016
- allowedPrefixes: null
1021
+ })
1022
+ ];
1023
+ if (options?.collaboration) {
1024
+ extensions.push(
1025
+ import_extension_collaboration.default.configure({
1026
+ document: options.collaboration.doc,
1027
+ field: options.collaboration.field
1028
+ })
1029
+ );
1030
+ if (options.collaboration.awareness) {
1031
+ extensions.push(
1032
+ import_extension_collaboration_cursor.default.configure({
1033
+ provider: options.collaboration.awareness,
1034
+ user: options.collaboration.awareness.user
1035
+ // The provider should hold the user info
1036
+ })
1037
+ );
1017
1038
  }
1018
- })
1019
- ];
1039
+ }
1040
+ return extensions;
1041
+ };
1020
1042
  var extension_kit_default = ExtensionKit;
1021
1043
 
1022
1044
  // src/react/menus/TextMenu.tsx
@@ -1905,8 +1927,8 @@ function ImageMenu({
1905
1927
  (0, import_react20.useEffect)(() => {
1906
1928
  if (!editor) return;
1907
1929
  const update = () => {
1908
- if (!editor.isActive("image")) return;
1909
- const attrs = editor.getAttributes("image") ?? {
1930
+ if (!editor.isActive("imageBlock")) return;
1931
+ const attrs = editor.getAttributes("imageBlock") ?? {
1910
1932
  width: "",
1911
1933
  align: "left"
1912
1934
  };
@@ -1931,27 +1953,24 @@ function ImageMenu({
1931
1953
  if (!editor) return null;
1932
1954
  const updateImageSize = (newSize) => {
1933
1955
  setSize(newSize);
1934
- editor.commands.updateAttributes("image", {
1935
- width: `${newSize}%`
1936
- });
1956
+ editor.commands.setImageBlockWidth(newSize);
1937
1957
  };
1938
1958
  const updateImageAlign = (newAlign) => {
1939
1959
  setAlign(newAlign);
1940
- editor.commands.updateAttributes("image", { align: newAlign });
1960
+ editor.commands.setImageBlockAlign(newAlign);
1941
1961
  };
1942
1962
  const removeImage = () => {
1943
1963
  editor.chain().focus().deleteSelection().run();
1944
1964
  };
1945
1965
  const triggerUpload = () => {
1946
- ;
1947
- editor.chain().focus().uploadImage().run();
1966
+ editor.commands.updateAttributes("imageBlock", { src: "", loading: false });
1948
1967
  };
1949
1968
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1950
1969
  import_menus3.BubbleMenu,
1951
1970
  {
1952
1971
  editor,
1953
1972
  shouldShow: ({ editor: e, state }) => {
1954
- if (!e.isActive("image")) return false;
1973
+ if (!e.isActive("imageBlock")) return false;
1955
1974
  const { selection } = state;
1956
1975
  const isNodeSelection = selection.constructor.name === "NodeSelection";
1957
1976
  return isNodeSelection;
@@ -2078,7 +2097,8 @@ function Editor2({
2078
2097
  bubbleMenuExtras,
2079
2098
  onUpdate,
2080
2099
  onCreate,
2081
- uploadImage
2100
+ uploadImage,
2101
+ collaboration
2082
2102
  }) {
2083
2103
  const normalizeExtras = (extras) => {
2084
2104
  const result = {
@@ -2104,7 +2124,10 @@ function Editor2({
2104
2124
  immediatelyRender,
2105
2125
  editable,
2106
2126
  content,
2107
- extensions: [...extension_kit_default({ uploadImage }), ...extensions ?? []],
2127
+ extensions: [
2128
+ ...extension_kit_default({ uploadImage, collaboration }),
2129
+ ...extensions ?? []
2130
+ ],
2108
2131
  editorProps: {
2109
2132
  attributes: {
2110
2133
  class: "nph-editor max-w-none outline-none"