neuphlo-editor 0.4.2 → 0.4.3
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/LICENSE +21 -0
- package/dist/chunk-3KATSGAJ.js +334 -0
- package/dist/chunk-3KATSGAJ.js.map +1 -0
- package/dist/chunk-3NZW7XQW.js +199 -0
- package/dist/chunk-3NZW7XQW.js.map +1 -0
- package/dist/chunk-3XGRNDIA.js +270 -0
- package/dist/chunk-3XGRNDIA.js.map +1 -0
- package/dist/chunk-42TQBICL.js +285 -0
- package/dist/chunk-42TQBICL.js.map +1 -0
- package/dist/chunk-4A4NLM4J.js +105 -0
- package/dist/chunk-4A4NLM4J.js.map +1 -0
- package/dist/chunk-4HTYZSZB.js +283 -0
- package/dist/chunk-4HTYZSZB.js.map +1 -0
- package/dist/chunk-52EDCGOT.js +283 -0
- package/dist/chunk-52EDCGOT.js.map +1 -0
- package/dist/chunk-5LHEWHX2.js +310 -0
- package/dist/chunk-5LHEWHX2.js.map +1 -0
- package/dist/chunk-5SICPLDM.js +162 -0
- package/dist/chunk-5SICPLDM.js.map +1 -0
- package/dist/chunk-5X66AJGZ.js +286 -0
- package/dist/chunk-5X66AJGZ.js.map +1 -0
- package/dist/chunk-66G4F3B7.js +293 -0
- package/dist/chunk-66G4F3B7.js.map +1 -0
- package/dist/chunk-6AT4Y6ZS.js +287 -0
- package/dist/chunk-6AT4Y6ZS.js.map +1 -0
- package/dist/chunk-6JV4E5XM.js +253 -0
- package/dist/chunk-6JV4E5XM.js.map +1 -0
- package/dist/chunk-7D4SUZUM.js +38 -0
- package/dist/chunk-7D4SUZUM.js.map +1 -0
- package/dist/chunk-7LA3T2ZZ.js +226 -0
- package/dist/chunk-7LA3T2ZZ.js.map +1 -0
- package/dist/chunk-A54YGOPF.js +158 -0
- package/dist/chunk-A54YGOPF.js.map +1 -0
- package/dist/chunk-A7P5CEXL.js +307 -0
- package/dist/chunk-A7P5CEXL.js.map +1 -0
- package/dist/chunk-AJKBB4BM.js +299 -0
- package/dist/chunk-AJKBB4BM.js.map +1 -0
- package/dist/chunk-AKTIMFVS.js +62 -0
- package/dist/chunk-AKTIMFVS.js.map +1 -0
- package/dist/chunk-BREFWGM6.js +324 -0
- package/dist/chunk-BREFWGM6.js.map +1 -0
- package/dist/chunk-BVJTDYXS.js +293 -0
- package/dist/chunk-BVJTDYXS.js.map +1 -0
- package/dist/chunk-CSNCOG2Q.js +267 -0
- package/dist/chunk-CSNCOG2Q.js.map +1 -0
- package/dist/chunk-CZP4MVGC.js +33 -0
- package/dist/chunk-CZP4MVGC.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-DHLYGW7C.js +296 -0
- package/dist/chunk-DHLYGW7C.js.map +1 -0
- package/dist/chunk-DLV6K2L6.js +300 -0
- package/dist/chunk-DLV6K2L6.js.map +1 -0
- package/dist/chunk-E4ZOKKFZ.js +104 -0
- package/dist/chunk-E4ZOKKFZ.js.map +1 -0
- package/dist/chunk-ES6CXFKY.js +253 -0
- package/dist/chunk-ES6CXFKY.js.map +1 -0
- package/dist/chunk-G4OUF5JM.js +420 -0
- package/dist/chunk-G4OUF5JM.js.map +1 -0
- package/dist/chunk-GMGPF7KX.js +286 -0
- package/dist/chunk-GMGPF7KX.js.map +1 -0
- package/dist/chunk-GWZ7IKMP.js +287 -0
- package/dist/chunk-GWZ7IKMP.js.map +1 -0
- package/dist/chunk-H3RFWADZ.js +1075 -0
- package/dist/chunk-H3RFWADZ.js.map +1 -0
- package/dist/chunk-H7Y3GE5V.js +283 -0
- package/dist/chunk-H7Y3GE5V.js.map +1 -0
- package/dist/chunk-HGYQOOPL.js +310 -0
- package/dist/chunk-HGYQOOPL.js.map +1 -0
- package/dist/chunk-HIVO3ILW.js +103 -0
- package/dist/chunk-HIVO3ILW.js.map +1 -0
- package/dist/chunk-I6DXZZPA.js +102 -0
- package/dist/chunk-I6DXZZPA.js.map +1 -0
- package/dist/chunk-IUKIZ4GW.js +310 -0
- package/dist/chunk-IUKIZ4GW.js.map +1 -0
- package/dist/chunk-JIFYPDKP.js +301 -0
- package/dist/chunk-JIFYPDKP.js.map +1 -0
- package/dist/chunk-K6SSIZS6.js +330 -0
- package/dist/chunk-K6SSIZS6.js.map +1 -0
- package/dist/chunk-LIFS45CU.js +253 -0
- package/dist/chunk-LIFS45CU.js.map +1 -0
- package/dist/chunk-LNTRIOFK.js +307 -0
- package/dist/chunk-LNTRIOFK.js.map +1 -0
- package/dist/chunk-LPFVU3RN.js +199 -0
- package/dist/chunk-LPFVU3RN.js.map +1 -0
- package/dist/chunk-LRHHHMXX.js +266 -0
- package/dist/chunk-LRHHHMXX.js.map +1 -0
- package/dist/chunk-MG2IC4MX.js +366 -0
- package/dist/chunk-MG2IC4MX.js.map +1 -0
- package/dist/chunk-NEDF73LE.js +417 -0
- package/dist/chunk-NEDF73LE.js.map +1 -0
- package/dist/chunk-NRJKIW5O.js +188 -0
- package/dist/chunk-NRJKIW5O.js.map +1 -0
- package/dist/chunk-O57IX4IM.js +968 -0
- package/dist/chunk-O57IX4IM.js.map +1 -0
- package/dist/chunk-OEM5TFNL.js +427 -0
- package/dist/chunk-OEM5TFNL.js.map +1 -0
- package/dist/chunk-PQFWSZCB.js +380 -0
- package/dist/chunk-PQFWSZCB.js.map +1 -0
- package/dist/chunk-Q6CNWILK.js +62 -0
- package/dist/chunk-Q6CNWILK.js.map +1 -0
- package/dist/chunk-QF6C4OCO.js +268 -0
- package/dist/chunk-QF6C4OCO.js.map +1 -0
- package/dist/chunk-RVYZO65R.js +253 -0
- package/dist/chunk-RVYZO65R.js.map +1 -0
- package/dist/chunk-T2K3KCWJ.js +105 -0
- package/dist/chunk-T2K3KCWJ.js.map +1 -0
- package/dist/chunk-U7GHNRXL.js +253 -0
- package/dist/chunk-U7GHNRXL.js.map +1 -0
- package/dist/chunk-VADPPD5C.js +373 -0
- package/dist/chunk-VADPPD5C.js.map +1 -0
- package/dist/chunk-VFXYNXYF.js +58 -0
- package/dist/chunk-VFXYNXYF.js.map +1 -0
- package/dist/chunk-VKFDJF4D.js +62 -0
- package/dist/chunk-VKFDJF4D.js.map +1 -0
- package/dist/chunk-VLANJDHQ.js +151 -0
- package/dist/chunk-VLANJDHQ.js.map +1 -0
- package/dist/chunk-VRVNV2QN.js +267 -0
- package/dist/chunk-VRVNV2QN.js.map +1 -0
- package/dist/chunk-WCNMYOTP.js +307 -0
- package/dist/chunk-WCNMYOTP.js.map +1 -0
- package/dist/chunk-X4ZZ6IGZ.js +375 -0
- package/dist/chunk-X4ZZ6IGZ.js.map +1 -0
- package/dist/chunk-X55UNGAX.js +324 -0
- package/dist/chunk-X55UNGAX.js.map +1 -0
- package/dist/chunk-XE6OD7SD.js +307 -0
- package/dist/chunk-XE6OD7SD.js.map +1 -0
- package/dist/chunk-XMG5QIMC.js +309 -0
- package/dist/chunk-XMG5QIMC.js.map +1 -0
- package/dist/chunk-Y5TGCVN7.js +22 -0
- package/dist/chunk-Y5TGCVN7.js.map +1 -0
- package/dist/chunk-YHUGKP3V.js +266 -0
- package/dist/chunk-YHUGKP3V.js.map +1 -0
- package/dist/chunk-YVGYHTU6.js +229 -0
- package/dist/chunk-YVGYHTU6.js.map +1 -0
- package/dist/chunk-ZIUSSGJN.js +268 -0
- package/dist/chunk-ZIUSSGJN.js.map +1 -0
- package/dist/chunk-ZPN4LHFS.js +1432 -0
- package/dist/chunk-ZPN4LHFS.js.map +1 -0
- package/dist/chunk-ZZERJHJE.js +319 -0
- package/dist/chunk-ZZERJHJE.js.map +1 -0
- package/dist/example/components/editor-bubble-item.d.ts +9 -0
- package/dist/example/components/editor-bubble-item.js +13 -0
- package/dist/example/components/editor-bubble.d.ts +7 -0
- package/dist/example/components/editor-bubble.js +51 -0
- package/dist/example/components/editor-command-item.d.ts +3 -0
- package/dist/example/components/editor-command-item.js +16 -0
- package/dist/example/components/editor-command.js +46 -0
- package/dist/example/components/editor.d.ts +21 -0
- package/dist/example/components/editor.js +13 -0
- package/dist/example/components/index.d.ts +8 -0
- package/dist/example/components/index.js +6 -0
- package/dist/example/extensions/ai-highlight.d.ts +31 -0
- package/dist/example/extensions/ai-highlight.js +83 -0
- package/dist/example/extensions/custom-keymap.d.ts +12 -0
- package/dist/example/extensions/custom-keymap.js +37 -0
- package/dist/example/extensions/image-resizer.d.ts +2 -0
- package/dist/example/extensions/image-resizer.js +51 -0
- package/dist/example/extensions/index.d.ts +25 -0
- package/dist/example/extensions/index.js +57 -0
- package/dist/example/extensions/mathematics.d.ts +40 -0
- package/dist/example/extensions/mathematics.js +116 -0
- package/dist/example/extensions/slash-command.d.ts +32 -0
- package/dist/example/extensions/slash-command.js +82 -0
- package/dist/example/extensions/twitter.d.ts +47 -0
- package/dist/example/extensions/twitter.js +85 -0
- package/dist/example/extensions/updated-image.d.ts +2 -0
- package/dist/example/extensions/updated-image.js +16 -0
- package/dist/example/index.d.ts +5 -0
- package/dist/example/index.js +10 -0
- package/dist/example/plugins/index.d.ts +1 -0
- package/dist/example/plugins/index.js +1 -0
- package/dist/example/plugins/upload-images.d.ts +13 -0
- package/dist/example/plugins/upload-images.js +121 -0
- package/dist/example/utils/atoms.d.ts +6 -0
- package/dist/example/utils/atoms.js +3 -0
- package/dist/example/utils/index.d.ts +5 -0
- package/dist/example/utils/index.js +41 -0
- package/dist/example/utils/store.d.ts +2 -0
- package/dist/example/utils/store.js +4 -0
- package/dist/headless/components/editor-bubble-item.d.ts +9 -0
- package/dist/headless/components/editor-bubble-item.js +29 -0
- package/dist/headless/components/editor-bubble.d.ts +7 -0
- package/dist/headless/components/editor-bubble.js +9 -0
- package/dist/headless/components/editor-command-item.d.ts +3 -0
- package/dist/headless/components/editor-command-item.js +18 -0
- package/dist/headless/components/editor-command.d.ts +10 -0
- package/dist/headless/components/editor-command.js +48 -0
- package/dist/headless/components/editor.d.ts +24 -0
- package/dist/headless/components/editor.js +13 -0
- package/dist/headless/extensions/CodeBlock/CodeBlock.d.ts +1 -0
- package/dist/headless/extensions/CodeBlock/CodeBlock.js +6 -0
- package/dist/headless/extensions/CodeBlock/index.d.ts +1 -0
- package/dist/headless/extensions/CodeBlock/index.js +1 -0
- package/dist/headless/extensions/Link/Link.d.ts +2 -0
- package/dist/headless/extensions/Link/Link.js +40 -0
- package/dist/headless/extensions/Link/index.d.ts +1 -0
- package/dist/headless/extensions/Link/index.js +1 -0
- package/dist/headless/extensions/SlashCommand/CommandButton.d.ts +9 -0
- package/dist/headless/extensions/SlashCommand/CommandButton.js +9 -0
- package/dist/headless/extensions/SlashCommand/MenuList.d.ts +4 -0
- package/dist/headless/extensions/SlashCommand/MenuList.js +91 -0
- package/dist/headless/extensions/SlashCommand/SlashCommand.d.ts +3 -0
- package/dist/headless/extensions/SlashCommand/SlashCommand.js +149 -0
- package/dist/headless/extensions/SlashCommand/groups.d.ts +3 -0
- package/dist/headless/extensions/SlashCommand/groups.js +184 -0
- package/dist/headless/extensions/SlashCommand/index.d.ts +1 -0
- package/dist/headless/extensions/SlashCommand/index.js +1 -0
- package/dist/headless/extensions/SlashCommand/types.d.ts +22 -0
- package/dist/headless/extensions/SlashCommand/types.js +1 -0
- package/dist/headless/extensions/extension-kit.d.ts +2 -0
- package/dist/headless/extensions/extension-kit.js +23 -0
- package/dist/headless/extensions/index.d.ts +4 -0
- package/dist/headless/extensions/index.js +5 -0
- package/dist/headless/extensions/slash-command.d.ts +36 -0
- package/dist/headless/extensions/slash-command.js +105 -0
- package/dist/headless/src/components/editor-bubble-item.d.ts +9 -0
- package/dist/headless/src/components/editor-bubble-item.js +13 -0
- package/dist/headless/src/components/editor-bubble.d.ts +7 -0
- package/dist/headless/src/components/editor-bubble.js +51 -0
- package/dist/headless/src/components/editor-command-item.d.ts +3 -0
- package/dist/headless/src/components/editor-command-item.js +16 -0
- package/dist/headless/src/components/editor-command.js +46 -0
- package/dist/headless/src/components/editor.d.ts +21 -0
- package/dist/headless/src/components/editor.js +13 -0
- package/dist/headless/src/components/index.d.ts +8 -0
- package/dist/headless/src/components/index.js +6 -0
- package/dist/headless/src/extensions/ai-highlight.d.ts +31 -0
- package/dist/headless/src/extensions/ai-highlight.js +83 -0
- package/dist/headless/src/extensions/custom-keymap.d.ts +12 -0
- package/dist/headless/src/extensions/custom-keymap.js +37 -0
- package/dist/headless/src/extensions/image-resizer.d.ts +2 -0
- package/dist/headless/src/extensions/image-resizer.js +51 -0
- package/dist/headless/src/extensions/index.d.ts +25 -0
- package/dist/headless/src/extensions/index.js +57 -0
- package/dist/headless/src/extensions/mathematics.d.ts +40 -0
- package/dist/headless/src/extensions/mathematics.js +116 -0
- package/dist/headless/src/extensions/slash-command.d.ts +32 -0
- package/dist/headless/src/extensions/slash-command.js +82 -0
- package/dist/headless/src/extensions/twitter.d.ts +47 -0
- package/dist/headless/src/extensions/twitter.js +85 -0
- package/dist/headless/src/extensions/updated-image.d.ts +2 -0
- package/dist/headless/src/extensions/updated-image.js +16 -0
- package/dist/headless/src/index.d.ts +5 -0
- package/dist/headless/src/index.js +10 -0
- package/dist/headless/src/plugins/index.d.ts +1 -0
- package/dist/headless/src/plugins/index.js +1 -0
- package/dist/headless/src/plugins/upload-images.d.ts +13 -0
- package/dist/headless/src/plugins/upload-images.js +121 -0
- package/dist/headless/src/utils/atoms.d.ts +6 -0
- package/dist/headless/src/utils/atoms.js +3 -0
- package/dist/headless/src/utils/index.d.ts +5 -0
- package/dist/headless/src/utils/index.js +41 -0
- package/dist/headless/src/utils/store.d.ts +2 -0
- package/dist/headless/src/utils/store.js +4 -0
- package/dist/headless/tsup.config.d.ts +3 -0
- package/dist/headless/tsup.config.js +13 -0
- package/dist/headless/utils/atoms.d.ts +7 -0
- package/dist/headless/utils/atoms.js +3 -0
- package/dist/headless/utils/command-renderer.d.ts +8 -0
- package/dist/headless/utils/command-renderer.js +52 -0
- package/dist/headless/utils/command-store.d.ts +16 -0
- package/dist/headless/utils/command-store.js +30 -0
- package/dist/headless/utils/store.d.ts +2 -0
- package/dist/headless/utils/store.js +4 -0
- package/dist/index.cjs +31 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/react/Editor.d.ts +14 -0
- package/dist/react/Editor.js +14 -0
- package/dist/react/EditorContent.d.ts +12 -0
- package/dist/react/EditorContent.js +13 -0
- package/dist/react/EditorRoot.d.ts +5 -0
- package/dist/react/EditorRoot.js +1 -0
- package/dist/react/core.cjs +154 -0
- package/dist/react/core.cjs.map +1 -0
- package/dist/react/core.d.cts +20 -0
- package/dist/react/core.d.ts +20 -0
- package/dist/react/core.js +10 -0
- package/dist/react/core.js.map +1 -0
- package/dist/react/index.cjs +90 -73
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +91 -74
- package/dist/react/index.js.map +1 -1
- package/dist/react/menus/LinkPopover.d.ts +9 -0
- package/dist/react/menus/LinkPopover.js +113 -0
- package/dist/react/menus/MenuList.d.ts +10 -0
- package/dist/react/menus/MenuList.js +94 -0
- package/dist/react/menus/SlashMenu.d.ts +5 -0
- package/dist/react/menus/SlashMenu.js +71 -0
- package/dist/react/menus/TextMenu.d.ts +6 -0
- package/dist/react/menus/TextMenu.js +67 -0
- package/dist/react/menus/TextMenu.withIcons.d.ts +3 -0
- package/dist/react/menus/TextMenu.withIcons.js +7 -0
- package/dist/react/menus/index.d.ts +4 -0
- package/dist/react/menus/index.js +2 -0
- package/package.json +9 -11
- package/dist/tailwind.css +0 -462
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Neuphlo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
18
|
+
|
|
19
|
+
// src/headless/index.ts
|
|
20
|
+
import { useCurrentEditor as useCurrentEditor4 } from "@tiptap/react";
|
|
21
|
+
|
|
22
|
+
// src/headless/components/editor.tsx
|
|
23
|
+
import { EditorProvider } from "@tiptap/react";
|
|
24
|
+
import { forwardRef } from "react";
|
|
25
|
+
import { Provider } from "jotai";
|
|
26
|
+
|
|
27
|
+
// src/headless/utils/store.ts
|
|
28
|
+
var store_exports = {};
|
|
29
|
+
__export(store_exports, {
|
|
30
|
+
novelStore: () => novelStore
|
|
31
|
+
});
|
|
32
|
+
__reExport(store_exports, jotai_star);
|
|
33
|
+
import { createStore } from "jotai";
|
|
34
|
+
import * as jotai_star from "jotai";
|
|
35
|
+
var novelStore = createStore();
|
|
36
|
+
|
|
37
|
+
// src/headless/components/editor.tsx
|
|
38
|
+
import { jsx } from "react/jsx-runtime";
|
|
39
|
+
var EditorRoot = ({ children }) => {
|
|
40
|
+
return /* @__PURE__ */ jsx(Provider, { store: novelStore, children });
|
|
41
|
+
};
|
|
42
|
+
var EditorContent = forwardRef(
|
|
43
|
+
({ className, children, initialContent, content, ...rest }, ref) => {
|
|
44
|
+
const effectiveContent = content ?? initialContent;
|
|
45
|
+
return /* @__PURE__ */ jsx("div", { ref, className, children: /* @__PURE__ */ jsx(EditorProvider, { ...rest, content: effectiveContent, children }) });
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
EditorContent.displayName = "EditorContent";
|
|
49
|
+
|
|
50
|
+
// src/headless/components/editor-bubble.tsx
|
|
51
|
+
import { useCurrentEditor } from "@tiptap/react";
|
|
52
|
+
import { BubbleMenu as BubbleMenuReact } from "@tiptap/react/menus";
|
|
53
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
54
|
+
function EditorBubble({ className, children, options }) {
|
|
55
|
+
const { editor } = useCurrentEditor();
|
|
56
|
+
if (!editor) return null;
|
|
57
|
+
return /* @__PURE__ */ jsx2(BubbleMenuReact, { editor, options, children: /* @__PURE__ */ jsx2("div", { className, children }) });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/headless/components/editor-bubble-item.tsx
|
|
61
|
+
import { forwardRef as forwardRef2, isValidElement, cloneElement } from "react";
|
|
62
|
+
import { useCurrentEditor as useCurrentEditor2 } from "@tiptap/react";
|
|
63
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
64
|
+
var EditorBubbleItem = forwardRef2(({ children, asChild, onSelect, ...rest }, ref) => {
|
|
65
|
+
const { editor } = useCurrentEditor2();
|
|
66
|
+
if (!editor) return null;
|
|
67
|
+
const handleClick = (e) => {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
onSelect?.(editor);
|
|
70
|
+
};
|
|
71
|
+
if (asChild && isValidElement(children)) {
|
|
72
|
+
const child = children;
|
|
73
|
+
const childOnClick = child.props?.onClick;
|
|
74
|
+
const mergedOnClick = (e) => {
|
|
75
|
+
childOnClick?.(e);
|
|
76
|
+
if (!e?.defaultPrevented) onSelect?.(editor);
|
|
77
|
+
};
|
|
78
|
+
return cloneElement(child, {
|
|
79
|
+
...rest,
|
|
80
|
+
ref: child.ref ?? ref,
|
|
81
|
+
onClick: mergedOnClick
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return /* @__PURE__ */ jsx3("div", { ref, ...rest, onClick: handleClick, children });
|
|
85
|
+
});
|
|
86
|
+
EditorBubbleItem.displayName = "EditorBubbleItem";
|
|
87
|
+
|
|
88
|
+
// src/headless/components/editor-command.tsx
|
|
89
|
+
import { useAtom, useSetAtom } from "jotai";
|
|
90
|
+
import { useEffect, forwardRef as forwardRef3 } from "react";
|
|
91
|
+
import { Command } from "cmdk";
|
|
92
|
+
|
|
93
|
+
// src/headless/utils/atoms.ts
|
|
94
|
+
import { atom } from "jotai";
|
|
95
|
+
var queryAtom = atom("");
|
|
96
|
+
var rangeAtom = atom(null);
|
|
97
|
+
|
|
98
|
+
// src/headless/components/editor-command.tsx
|
|
99
|
+
import tunnel from "tunnel-rat";
|
|
100
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
101
|
+
var commandTunnel = tunnel();
|
|
102
|
+
var EditorCommandOut = ({
|
|
103
|
+
query,
|
|
104
|
+
range
|
|
105
|
+
}) => {
|
|
106
|
+
const setQuery = useSetAtom(queryAtom, { store: novelStore });
|
|
107
|
+
const setRange = useSetAtom(rangeAtom, { store: novelStore });
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
setQuery(query);
|
|
110
|
+
}, [query, setQuery]);
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
setRange(range);
|
|
113
|
+
}, [range, setRange]);
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
const navigationKeys = ["ArrowUp", "ArrowDown", "Enter"];
|
|
116
|
+
const onKeyDown = (e) => {
|
|
117
|
+
if (navigationKeys.includes(e.key)) {
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
const commandRef = document.querySelector("#slash-command");
|
|
120
|
+
if (commandRef)
|
|
121
|
+
commandRef.dispatchEvent(
|
|
122
|
+
new KeyboardEvent("keydown", {
|
|
123
|
+
key: e.key,
|
|
124
|
+
cancelable: true,
|
|
125
|
+
bubbles: true
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
document.addEventListener("keydown", onKeyDown);
|
|
132
|
+
return () => {
|
|
133
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
134
|
+
};
|
|
135
|
+
}, []);
|
|
136
|
+
return /* @__PURE__ */ jsx4(commandTunnel.Out, {});
|
|
137
|
+
};
|
|
138
|
+
var CommandAny = Command;
|
|
139
|
+
var EditorCommand = forwardRef3(
|
|
140
|
+
({ children, className, ...rest }, ref) => {
|
|
141
|
+
const [query, setQuery] = useAtom(queryAtom);
|
|
142
|
+
return /* @__PURE__ */ jsx4(commandTunnel.In, { children: /* @__PURE__ */ jsxs(
|
|
143
|
+
CommandAny,
|
|
144
|
+
{
|
|
145
|
+
ref,
|
|
146
|
+
onKeyDown: (e) => {
|
|
147
|
+
e.stopPropagation();
|
|
148
|
+
},
|
|
149
|
+
id: "slash-command",
|
|
150
|
+
className,
|
|
151
|
+
...rest,
|
|
152
|
+
children: [
|
|
153
|
+
/* @__PURE__ */ jsx4(
|
|
154
|
+
CommandAny.Input,
|
|
155
|
+
{
|
|
156
|
+
value: query,
|
|
157
|
+
onValueChange: setQuery,
|
|
158
|
+
style: { display: "none" }
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
children
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
) });
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
var EditorCommandList = Command.List;
|
|
168
|
+
EditorCommand.displayName = "EditorCommand";
|
|
169
|
+
|
|
170
|
+
// src/headless/components/editor-command-item.tsx
|
|
171
|
+
import { forwardRef as forwardRef4 } from "react";
|
|
172
|
+
import { CommandEmpty, CommandItem } from "cmdk";
|
|
173
|
+
import { useCurrentEditor as useCurrentEditor3 } from "@tiptap/react";
|
|
174
|
+
import { useAtomValue } from "jotai";
|
|
175
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
176
|
+
var CommandItemAny = CommandItem;
|
|
177
|
+
var EditorCommandItem = forwardRef4(({ children, onCommand, ...rest }, ref) => {
|
|
178
|
+
const { editor } = useCurrentEditor3();
|
|
179
|
+
const range = useAtomValue(rangeAtom);
|
|
180
|
+
if (!editor || !range) return null;
|
|
181
|
+
return /* @__PURE__ */ jsx5(
|
|
182
|
+
CommandItemAny,
|
|
183
|
+
{
|
|
184
|
+
ref,
|
|
185
|
+
...rest,
|
|
186
|
+
onSelect: () => onCommand({ editor, range }),
|
|
187
|
+
children
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
EditorCommandItem.displayName = "EditorCommandItem";
|
|
192
|
+
|
|
193
|
+
// src/headless/extensions/index.ts
|
|
194
|
+
import { StarterKit } from "@tiptap/starter-kit";
|
|
195
|
+
import { Placeholder } from "@tiptap/extension-placeholder";
|
|
196
|
+
|
|
197
|
+
// src/headless/extensions/CodeBlock/CodeBlock.ts
|
|
198
|
+
import { CodeBlockLowlight } from "@tiptap/extension-code-block-lowlight";
|
|
199
|
+
import { createLowlight } from "lowlight";
|
|
200
|
+
import css from "highlight.js/lib/languages/css";
|
|
201
|
+
import js from "highlight.js/lib/languages/javascript";
|
|
202
|
+
import ts from "highlight.js/lib/languages/typescript";
|
|
203
|
+
import html from "highlight.js/lib/languages/xml";
|
|
204
|
+
var lowlight = createLowlight();
|
|
205
|
+
lowlight.register("html", html);
|
|
206
|
+
lowlight.register("css", css);
|
|
207
|
+
lowlight.register("js", js);
|
|
208
|
+
lowlight.register("ts", ts);
|
|
209
|
+
lowlight.register("javascript", js);
|
|
210
|
+
lowlight.register("typescript", ts);
|
|
211
|
+
var CodeBlock = CodeBlockLowlight.configure({
|
|
212
|
+
lowlight
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// src/headless/extensions/slash-command.tsx
|
|
216
|
+
import { ReactRenderer } from "@tiptap/react";
|
|
217
|
+
import Suggestion from "@tiptap/suggestion";
|
|
218
|
+
import { Extension } from "@tiptap/core";
|
|
219
|
+
var Command2 = Extension.create({
|
|
220
|
+
name: "slash-command",
|
|
221
|
+
addOptions() {
|
|
222
|
+
return {
|
|
223
|
+
suggestion: {
|
|
224
|
+
char: "/",
|
|
225
|
+
command: (ctx) => {
|
|
226
|
+
ctx.props.command({ editor: ctx.editor, range: ctx.range });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
addProseMirrorPlugins() {
|
|
232
|
+
const base = this.options.suggestion ?? {};
|
|
233
|
+
return [
|
|
234
|
+
Suggestion({
|
|
235
|
+
editor: this.editor,
|
|
236
|
+
char: base.char ?? "/",
|
|
237
|
+
items: base.items ?? (() => ["/"]),
|
|
238
|
+
command: (ctx) => {
|
|
239
|
+
if (typeof ctx?.props?.command === "function") {
|
|
240
|
+
ctx.props.command({ editor: ctx.editor, range: ctx.range });
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
...base
|
|
244
|
+
})
|
|
245
|
+
];
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
var renderItems = (elementRef) => {
|
|
249
|
+
let component = null;
|
|
250
|
+
let container = null;
|
|
251
|
+
const destroy = () => {
|
|
252
|
+
component?.destroy();
|
|
253
|
+
component = null;
|
|
254
|
+
if (container) {
|
|
255
|
+
container.remove();
|
|
256
|
+
container = null;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const updatePosition = (clientRect) => {
|
|
260
|
+
if (!container || !clientRect) return;
|
|
261
|
+
const top = Math.round(clientRect.bottom + 8);
|
|
262
|
+
const left = Math.round(clientRect.left);
|
|
263
|
+
container.style.top = `${top}px`;
|
|
264
|
+
container.style.left = `${left}px`;
|
|
265
|
+
};
|
|
266
|
+
return {
|
|
267
|
+
onStart: (props) => {
|
|
268
|
+
const { selection } = props.editor.state;
|
|
269
|
+
const parentNode = selection.$from.node(selection.$from.depth);
|
|
270
|
+
const blockType = parentNode.type.name;
|
|
271
|
+
if (blockType === "codeBlock") return false;
|
|
272
|
+
component = new ReactRenderer(EditorCommandOut, {
|
|
273
|
+
props: {
|
|
274
|
+
query: props.query ?? "",
|
|
275
|
+
range: props.range
|
|
276
|
+
},
|
|
277
|
+
editor: props.editor
|
|
278
|
+
});
|
|
279
|
+
container = document.createElement("div");
|
|
280
|
+
container.style.position = "fixed";
|
|
281
|
+
container.style.zIndex = "9999";
|
|
282
|
+
container.style.minWidth = "240px";
|
|
283
|
+
(elementRef?.current ?? document.body).appendChild(container);
|
|
284
|
+
container.appendChild(component.element);
|
|
285
|
+
const rect = typeof props.clientRect === "function" ? props.clientRect() : null;
|
|
286
|
+
if (rect) updatePosition(rect);
|
|
287
|
+
},
|
|
288
|
+
onUpdate: (props) => {
|
|
289
|
+
component?.updateProps({
|
|
290
|
+
query: props.query ?? "",
|
|
291
|
+
range: props.range
|
|
292
|
+
});
|
|
293
|
+
const rect = typeof props.clientRect === "function" ? props.clientRect() : null;
|
|
294
|
+
if (rect) updatePosition(rect);
|
|
295
|
+
},
|
|
296
|
+
onKeyDown: ({ event }) => {
|
|
297
|
+
if (event.key === "Escape") {
|
|
298
|
+
destroy();
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
},
|
|
303
|
+
onExit: () => {
|
|
304
|
+
destroy();
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
var createSuggestionItems = (items) => items;
|
|
309
|
+
var handleCommandNavigation = (event) => {
|
|
310
|
+
if (["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) {
|
|
311
|
+
const slashCommand = document.querySelector("#slash-command");
|
|
312
|
+
if (slashCommand) return true;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
export {
|
|
317
|
+
EditorRoot,
|
|
318
|
+
EditorContent,
|
|
319
|
+
EditorBubble,
|
|
320
|
+
EditorBubbleItem,
|
|
321
|
+
EditorCommandOut,
|
|
322
|
+
EditorCommand,
|
|
323
|
+
EditorCommandList,
|
|
324
|
+
EditorCommandItem,
|
|
325
|
+
CodeBlock,
|
|
326
|
+
StarterKit,
|
|
327
|
+
Placeholder,
|
|
328
|
+
Command2 as Command,
|
|
329
|
+
renderItems,
|
|
330
|
+
createSuggestionItems,
|
|
331
|
+
handleCommandNavigation,
|
|
332
|
+
useCurrentEditor4 as useCurrentEditor
|
|
333
|
+
};
|
|
334
|
+
//# sourceMappingURL=chunk-3KATSGAJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/headless/index.ts","../src/headless/components/editor.tsx","../src/headless/utils/store.ts","../src/headless/components/editor-bubble.tsx","../src/headless/components/editor-bubble-item.tsx","../src/headless/components/editor-command.tsx","../src/headless/utils/atoms.ts","../src/headless/components/editor-command-item.tsx","../src/headless/extensions/index.ts","../src/headless/extensions/CodeBlock/CodeBlock.ts","../src/headless/extensions/slash-command.tsx"],"sourcesContent":["export { useCurrentEditor as useEditor } from \"@tiptap/react\"\n\nexport {\n EditorRoot,\n EditorContent,\n type EditorContentProps,\n} from \"./components/editor\"\n\nexport { EditorBubble } from \"./components/editor-bubble\"\nexport { EditorBubbleItem } from \"./components/editor-bubble-item\"\nexport {\n EditorCommand,\n EditorCommandList,\n EditorCommandOut,\n} from \"./components/editor-command\"\nexport { EditorCommandItem } from \"./components/editor-command-item\"\n\nexport { Placeholder, StarterKit } from \"./extensions\"\nexport {\n Command as SlashCommand,\n renderItems as renderSlashCommandItems,\n createSuggestionItems,\n handleCommandNavigation,\n} from \"./extensions/slash-command\"\n// Path without extension to satisfy TS/tsup\n// (the file is at ./extensions/slash-command.tsx)\n// eslint-disable-next-line\n","import { EditorProvider } from \"@tiptap/react\"\nimport type { EditorProviderProps } from \"@tiptap/react\"\nimport { forwardRef } from \"react\"\nimport type { FC, ReactNode } from \"react\"\nimport { Provider } from \"jotai\"\nimport { novelStore } from \"../utils/store\"\n\nexport interface EditorRootProps {\n readonly children: ReactNode\n}\n\nexport const EditorRoot: FC<EditorRootProps> = ({ children }) => {\n return (\n <Provider store={novelStore as any}>\n {children as any}\n </Provider>\n )\n}\n\nexport type EditorContentProps = EditorProviderProps & {\n readonly children?: ReactNode\n readonly className?: string\n readonly initialContent?: any\n}\n\nexport const EditorContent = forwardRef<HTMLDivElement, EditorContentProps>(\n ({ className, children, initialContent, content, ...rest }, ref) => {\n const effectiveContent = content ?? initialContent\n return (\n <div ref={ref} className={className}>\n <EditorProvider {...rest} content={effectiveContent}>\n {children}\n </EditorProvider>\n </div>\n )\n }\n)\n\nEditorContent.displayName = \"EditorContent\"\n","import { createStore } from \"jotai\";\n\n// biome-ignore lint/suspicious/noExplicitAny: store is opaque to consumers\nexport const novelStore: any = createStore();\nexport * from \"jotai\";\n\n","import { useCurrentEditor } from \"@tiptap/react\";\nimport { BubbleMenu as BubbleMenuReact } from \"@tiptap/react/menus\";\nimport type { ReactNode } from \"react\";\n\nexport interface EditorBubbleProps {\n readonly className?: string;\n readonly children: ReactNode;\n readonly options?: Record<string, unknown>;\n}\n\nexport function EditorBubble({ className, children, options }: EditorBubbleProps) {\n const { editor } = useCurrentEditor();\n if (!editor) return null;\n\n return (\n <BubbleMenuReact editor={editor} options={options}>\n <div className={className}>{children}</div>\n </BubbleMenuReact>\n );\n}\n","import { forwardRef, isValidElement, cloneElement } from \"react\"\nimport type { ComponentPropsWithoutRef, ReactElement, ReactNode } from \"react\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport type { Editor as TiptapEditor } from \"@tiptap/react\"\n\ninterface EditorBubbleItemProps {\n readonly children: ReactNode\n readonly asChild?: boolean\n readonly onSelect?: (editor: TiptapEditor) => void\n}\n\nexport const EditorBubbleItem = forwardRef<\n HTMLDivElement,\n EditorBubbleItemProps & Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\">\n>(({ children, asChild, onSelect, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n\n if (!editor) return null\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault()\n onSelect?.(editor)\n }\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<any>\n const childOnClick = (child.props as any)?.onClick as\n | ((e: any) => void)\n | undefined\n const mergedOnClick = (e: any) => {\n childOnClick?.(e)\n if (!e?.defaultPrevented) onSelect?.(editor)\n }\n\n return cloneElement(child, {\n ...rest,\n ref: (child as any).ref ?? ref,\n onClick: mergedOnClick,\n })\n }\n\n return (\n <div ref={ref} {...rest} onClick={handleClick}>\n {children}\n </div>\n )\n})\n\nEditorBubbleItem.displayName = \"EditorBubbleItem\"\n\nexport default EditorBubbleItem\n","import { useAtom, useSetAtom } from \"jotai\"\nimport { useEffect, forwardRef } from \"react\"\nimport { Command } from \"cmdk\"\nimport { queryAtom, rangeAtom } from \"../utils/atoms\"\nimport { novelStore } from \"../utils/store\"\nimport type { FC } from \"react\"\nimport type { Range } from \"@tiptap/core\"\nimport tunnel from \"tunnel-rat\"\n\nconst commandTunnel: any = (tunnel as any)()\n\ninterface EditorCommandOutProps {\n readonly query: string\n readonly range: Range\n}\n\nexport const EditorCommandOut: FC<EditorCommandOutProps> = ({\n query,\n range,\n}) => {\n const setQuery = useSetAtom(queryAtom, { store: novelStore })\n const setRange = useSetAtom(rangeAtom, { store: novelStore })\n\n useEffect(() => {\n setQuery(query)\n }, [query, setQuery])\n\n useEffect(() => {\n setRange(range)\n }, [range, setRange])\n\n useEffect(() => {\n const navigationKeys = [\"ArrowUp\", \"ArrowDown\", \"Enter\"]\n const onKeyDown = (e: KeyboardEvent) => {\n if (navigationKeys.includes(e.key)) {\n e.preventDefault()\n const commandRef = document.querySelector(\"#slash-command\")\n\n if (commandRef)\n commandRef.dispatchEvent(\n new KeyboardEvent(\"keydown\", {\n key: e.key,\n cancelable: true,\n bubbles: true,\n })\n )\n\n return false\n }\n }\n document.addEventListener(\"keydown\", onKeyDown)\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown)\n }\n }, [])\n\n return <commandTunnel.Out />\n}\n\nconst CommandAny: any = Command\nexport const EditorCommand = forwardRef<HTMLDivElement, any>(\n ({ children, className, ...rest }, ref) => {\n const [query, setQuery] = useAtom(queryAtom)\n\n return (\n <commandTunnel.In>\n <CommandAny\n ref={ref}\n onKeyDown={(e: any) => {\n e.stopPropagation()\n }}\n id=\"slash-command\"\n className={className}\n {...rest}\n >\n <CommandAny.Input\n value={query}\n onValueChange={setQuery}\n style={{ display: \"none\" }}\n />\n {children}\n </CommandAny>\n </commandTunnel.In>\n )\n }\n)\nexport const EditorCommandList: any = Command.List\n\nEditorCommand.displayName = \"EditorCommand\"\n","import { atom } from \"jotai\"\nimport type { Range } from \"@tiptap/core\"\n\nexport const queryAtom = atom(\"\")\nexport const rangeAtom = atom<Range | null>(null)\n\n","import { forwardRef } from \"react\"\nimport { CommandEmpty, CommandItem } from \"cmdk\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport { useAtomValue } from \"jotai\"\nimport { rangeAtom } from \"../utils/atoms\"\nimport type { Editor, Range } from \"@tiptap/core\"\n\ninterface EditorCommandItemProps {\n readonly onCommand: ({\n editor,\n range,\n }: {\n editor: Editor\n range: Range\n }) => void\n}\n\nconst CommandItemAny: any = CommandItem\nconst CommandEmptyAny: any = CommandEmpty\n\nexport const EditorCommandItem = forwardRef<\n HTMLDivElement,\n EditorCommandItemProps & any\n>(({ children, onCommand, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n const range = useAtomValue(rangeAtom)\n\n if (!editor || !range) return null\n\n return (\n <CommandItemAny\n ref={ref}\n {...(rest as any)}\n onSelect={() => onCommand({ editor, range })}\n >\n {children}\n </CommandItemAny>\n )\n})\n\nEditorCommandItem.displayName = \"EditorCommandItem\"\n\nexport const EditorCommandEmpty: any = CommandEmptyAny\n\nexport default EditorCommandItem\n","export { StarterKit } from \"@tiptap/starter-kit\"\nexport { Placeholder } from \"@tiptap/extension-placeholder\"\n\n// Custom\nexport { CodeBlock } from \"./CodeBlock\"\n","import { CodeBlockLowlight } from \"@tiptap/extension-code-block-lowlight\"\nimport { createLowlight } from \"lowlight\"\n// Register specific highlight.js languages explicitly\nimport css from \"highlight.js/lib/languages/css\"\nimport js from \"highlight.js/lib/languages/javascript\"\nimport ts from \"highlight.js/lib/languages/typescript\"\nimport html from \"highlight.js/lib/languages/xml\"\n\nconst lowlight = createLowlight()\n\n// Register common languages and aliases\nlowlight.register(\"html\", html)\nlowlight.register(\"css\", css)\nlowlight.register(\"js\", js)\nlowlight.register(\"ts\", ts)\n// Optional explicit names\nlowlight.register(\"javascript\", js)\nlowlight.register(\"typescript\", ts)\n\nexport const CodeBlock = CodeBlockLowlight.configure({\n lowlight,\n})\n","import { ReactRenderer } from \"@tiptap/react\"\nimport Suggestion from \"@tiptap/suggestion\"\nimport { Extension } from \"@tiptap/core\"\nimport type { RefObject, ReactNode } from \"react\"\nimport { EditorCommandOut } from \"../components/editor-command\"\n\nexport const Command = Extension.create({\n name: \"slash-command\",\n addOptions() {\n return {\n suggestion: {\n char: \"/\",\n command: (ctx: any) => {\n ctx.props.command({ editor: ctx.editor, range: ctx.range })\n },\n } as any,\n }\n },\n addProseMirrorPlugins() {\n const base: any = this.options.suggestion ?? {}\n return [\n Suggestion({\n editor: this.editor,\n char: base.char ?? \"/\",\n items: base.items ?? (() => [\"/\"] as any),\n command: (ctx: any) => {\n if (typeof ctx?.props?.command === \"function\") {\n ctx.props.command({ editor: ctx.editor, range: ctx.range })\n }\n },\n ...base,\n }),\n ]\n },\n})\n\nexport const renderItems = (elementRef?: RefObject<Element> | null) => {\n let component: ReactRenderer | null = null\n let container: HTMLElement | null = null\n\n const destroy = () => {\n component?.destroy()\n component = null\n if (container) {\n container.remove()\n container = null\n }\n }\n\n const updatePosition = (clientRect?: DOMRect | null) => {\n if (!container || !clientRect) return\n const top = Math.round(clientRect.bottom + 8)\n const left = Math.round(clientRect.left)\n container.style.top = `${top}px`\n container.style.left = `${left}px`\n }\n\n return {\n onStart: (props: {\n editor: any\n clientRect: (() => DOMRect | null) | null\n query?: string\n range?: any\n }) => {\n const { selection } = props.editor.state\n const parentNode = selection.$from.node(selection.$from.depth)\n const blockType = parentNode.type.name\n if (blockType === \"codeBlock\") return false\n\n component = new ReactRenderer(EditorCommandOut, {\n props: {\n query: (props as any).query ?? \"\",\n range: (props as any).range,\n },\n editor: props.editor,\n })\n\n container = document.createElement(\"div\")\n container.style.position = \"fixed\"\n container.style.zIndex = \"9999\"\n container.style.minWidth = \"240px\"\n ;(elementRef?.current ?? document.body).appendChild(container)\n container.appendChild(component.element)\n\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onUpdate: (props: {\n editor: any\n clientRect: (() => DOMRect | null) | null\n query?: string\n range?: any\n }) => {\n component?.updateProps({\n query: (props as any).query ?? \"\",\n range: (props as any).range,\n })\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"Escape\") {\n destroy()\n return true\n }\n return false\n },\n onExit: () => {\n destroy()\n },\n }\n}\n\nexport interface SuggestionItem {\n title: string\n description: string\n icon: ReactNode\n searchTerms?: string[]\n command?: (props: {\n editor: any\n range: { from: number; to: number }\n }) => void\n}\n\nexport const createSuggestionItems = (items: SuggestionItem[]) => items\n\nexport const handleCommandNavigation = (event: KeyboardEvent) => {\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n const slashCommand = document.querySelector(\"#slash-command\")\n if (slashCommand) return true\n }\n}\n"],"mappings":"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","names":["useCurrentEditor","jsx","forwardRef","useCurrentEditor","jsx","forwardRef","jsx","forwardRef","forwardRef","useCurrentEditor","jsx","forwardRef","useCurrentEditor","jsx","Command"]}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// src/headless/index.ts
|
|
2
|
+
import { useCurrentEditor as useCurrentEditor3 } from "@tiptap/react";
|
|
3
|
+
|
|
4
|
+
// src/headless/components/editor.tsx
|
|
5
|
+
import { EditorProvider } from "@tiptap/react";
|
|
6
|
+
import { forwardRef } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
var EditorRoot = ({ children }) => children;
|
|
9
|
+
var EditorContent = forwardRef(
|
|
10
|
+
({ className, children, initialContent, content, ...rest }, ref) => {
|
|
11
|
+
const effectiveContent = content ?? initialContent;
|
|
12
|
+
return /* @__PURE__ */ jsx("div", { ref, className, children: /* @__PURE__ */ jsx(EditorProvider, { ...rest, content: effectiveContent, children }) });
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
EditorContent.displayName = "EditorContent";
|
|
16
|
+
|
|
17
|
+
// src/headless/components/editor-bubble.tsx
|
|
18
|
+
import { useCurrentEditor } from "@tiptap/react";
|
|
19
|
+
import { BubbleMenu as BubbleMenuReact } from "@tiptap/react/menus";
|
|
20
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
21
|
+
function EditorBubble({ className, children, options }) {
|
|
22
|
+
const { editor } = useCurrentEditor();
|
|
23
|
+
if (!editor) return null;
|
|
24
|
+
return /* @__PURE__ */ jsx2(BubbleMenuReact, { editor, options, children: /* @__PURE__ */ jsx2("div", { className, children }) });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/headless/components/editor-bubble-item.tsx
|
|
28
|
+
import { forwardRef as forwardRef2, isValidElement, cloneElement } from "react";
|
|
29
|
+
import { useCurrentEditor as useCurrentEditor2 } from "@tiptap/react";
|
|
30
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
31
|
+
var EditorBubbleItem = forwardRef2(({ children, asChild, onSelect, ...rest }, ref) => {
|
|
32
|
+
const { editor } = useCurrentEditor2();
|
|
33
|
+
if (!editor) return null;
|
|
34
|
+
const handleClick = (e) => {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
onSelect?.(editor);
|
|
37
|
+
};
|
|
38
|
+
if (asChild && isValidElement(children)) {
|
|
39
|
+
const child = children;
|
|
40
|
+
const childOnClick = child.props?.onClick;
|
|
41
|
+
const mergedOnClick = (e) => {
|
|
42
|
+
childOnClick?.(e);
|
|
43
|
+
if (!e?.defaultPrevented) onSelect?.(editor);
|
|
44
|
+
};
|
|
45
|
+
return cloneElement(child, {
|
|
46
|
+
...rest,
|
|
47
|
+
ref: child.ref ?? ref,
|
|
48
|
+
onClick: mergedOnClick
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return /* @__PURE__ */ jsx3("div", { ref, ...rest, onClick: handleClick, children });
|
|
52
|
+
});
|
|
53
|
+
EditorBubbleItem.displayName = "EditorBubbleItem";
|
|
54
|
+
|
|
55
|
+
// src/headless/components/editor-command.tsx
|
|
56
|
+
import {
|
|
57
|
+
createContext,
|
|
58
|
+
forwardRef as forwardRef3,
|
|
59
|
+
useContext,
|
|
60
|
+
useEffect,
|
|
61
|
+
useMemo,
|
|
62
|
+
useState
|
|
63
|
+
} from "react";
|
|
64
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
65
|
+
var EditorCommandContext = createContext(null);
|
|
66
|
+
var EditorCommand = forwardRef3(
|
|
67
|
+
({ className, children, ...rest }, ref) => {
|
|
68
|
+
const [query, setQuery] = useState("");
|
|
69
|
+
const [range, setRange] = useState(null);
|
|
70
|
+
const value = useMemo(
|
|
71
|
+
() => ({ query, setQuery, range, setRange }),
|
|
72
|
+
[query, range]
|
|
73
|
+
);
|
|
74
|
+
return /* @__PURE__ */ jsx4(EditorCommandContext.Provider, { value, children: /* @__PURE__ */ jsxs(
|
|
75
|
+
"div",
|
|
76
|
+
{
|
|
77
|
+
ref,
|
|
78
|
+
id: "nph-slash-command",
|
|
79
|
+
className: ["nph-command", className].filter(Boolean).join(" "),
|
|
80
|
+
onKeyDown: (e) => {
|
|
81
|
+
if (["ArrowUp", "ArrowDown", "Enter"].includes(e.key)) {
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
...rest,
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ jsx4(
|
|
88
|
+
"input",
|
|
89
|
+
{
|
|
90
|
+
style: { display: "none" },
|
|
91
|
+
value: query,
|
|
92
|
+
onChange: (e) => setQuery(e.target.value)
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
children
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
) });
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
EditorCommand.displayName = "EditorCommand";
|
|
102
|
+
var EditorCommandList = forwardRef3(({ className, children, ...rest }, ref) => /* @__PURE__ */ jsx4(
|
|
103
|
+
"ul",
|
|
104
|
+
{
|
|
105
|
+
ref,
|
|
106
|
+
role: "listbox",
|
|
107
|
+
className: ["nph-command__list", className].filter(Boolean).join(" "),
|
|
108
|
+
...rest,
|
|
109
|
+
children
|
|
110
|
+
}
|
|
111
|
+
));
|
|
112
|
+
EditorCommandList.displayName = "EditorCommandList";
|
|
113
|
+
var EditorCommandOut = ({
|
|
114
|
+
query,
|
|
115
|
+
range
|
|
116
|
+
}) => {
|
|
117
|
+
const ctx = useContext(EditorCommandContext);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
ctx?.setQuery(query);
|
|
120
|
+
}, [query]);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
ctx?.setRange(range);
|
|
123
|
+
}, [range]);
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
const navigationKeys = ["ArrowUp", "ArrowDown", "Enter"];
|
|
126
|
+
const onKeyDown = (e) => {
|
|
127
|
+
if (navigationKeys.includes(e.key)) {
|
|
128
|
+
e.preventDefault();
|
|
129
|
+
const commandRef = document.querySelector("#nph-slash-command");
|
|
130
|
+
if (commandRef)
|
|
131
|
+
commandRef.dispatchEvent(
|
|
132
|
+
new KeyboardEvent("keydown", {
|
|
133
|
+
key: e.key,
|
|
134
|
+
cancelable: true,
|
|
135
|
+
bubbles: true
|
|
136
|
+
})
|
|
137
|
+
);
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
document.addEventListener("keydown", onKeyDown);
|
|
142
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
143
|
+
}, []);
|
|
144
|
+
return null;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/headless/components/editor-command-item.tsx
|
|
148
|
+
import { forwardRef as forwardRef4 } from "react";
|
|
149
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
150
|
+
var EditorCommandItem = forwardRef4(
|
|
151
|
+
({ className, active, onSelect, children, ...rest }, ref) => /* @__PURE__ */ jsx5(
|
|
152
|
+
"li",
|
|
153
|
+
{
|
|
154
|
+
ref,
|
|
155
|
+
role: "option",
|
|
156
|
+
"aria-selected": !!active,
|
|
157
|
+
className: [
|
|
158
|
+
"nph-command__item",
|
|
159
|
+
active ? "is-active" : void 0,
|
|
160
|
+
className
|
|
161
|
+
].filter(Boolean).join(" "),
|
|
162
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
163
|
+
onClick: onSelect,
|
|
164
|
+
...rest,
|
|
165
|
+
children
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
);
|
|
169
|
+
EditorCommandItem.displayName = "EditorCommandItem";
|
|
170
|
+
|
|
171
|
+
// src/headless/extensions/index.ts
|
|
172
|
+
import PlaceholderExt from "@tiptap/extension-placeholder";
|
|
173
|
+
import { StarterKit } from "@tiptap/starter-kit";
|
|
174
|
+
var Placeholder = PlaceholderExt.configure({
|
|
175
|
+
placeholder: ({ node }) => {
|
|
176
|
+
if (node.type.name === "heading") {
|
|
177
|
+
return `Heading ${node.attrs.level}`;
|
|
178
|
+
}
|
|
179
|
+
return "Press '/' for commands";
|
|
180
|
+
},
|
|
181
|
+
includeChildren: true
|
|
182
|
+
});
|
|
183
|
+
var defaultExtensions = [Placeholder];
|
|
184
|
+
|
|
185
|
+
export {
|
|
186
|
+
EditorRoot,
|
|
187
|
+
EditorContent,
|
|
188
|
+
EditorBubble,
|
|
189
|
+
EditorBubbleItem,
|
|
190
|
+
EditorCommand,
|
|
191
|
+
EditorCommandList,
|
|
192
|
+
EditorCommandOut,
|
|
193
|
+
EditorCommandItem,
|
|
194
|
+
Placeholder,
|
|
195
|
+
defaultExtensions,
|
|
196
|
+
StarterKit,
|
|
197
|
+
useCurrentEditor3 as useCurrentEditor
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=chunk-3NZW7XQW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/headless/index.ts","../src/headless/components/editor.tsx","../src/headless/components/editor-bubble.tsx","../src/headless/components/editor-bubble-item.tsx","../src/headless/components/editor-command.tsx","../src/headless/components/editor-command-item.tsx","../src/headless/extensions/index.ts"],"sourcesContent":["export { useCurrentEditor as useEditor } from \"@tiptap/react\"\n\nexport {\n EditorRoot,\n EditorContent,\n type EditorContentProps,\n} from \"./components/editor\"\n\nexport { EditorBubble } from \"./components/editor-bubble\"\nexport { EditorBubbleItem } from \"./components/editor-bubble-item\"\nexport {\n EditorCommand,\n EditorCommandList,\n EditorCommandOut,\n} from \"./components/editor-command\"\nexport { EditorCommandItem } from \"./components/editor-command-item\"\n\nexport { SlashCommand, Placeholder, StarterKit } from \"./extensions\"\n","import { EditorProvider } from \"@tiptap/react\"\nimport type { EditorProviderProps } from \"@tiptap/react\"\nimport { forwardRef } from \"react\"\nimport type { FC, ReactNode } from \"react\"\n\nexport interface EditorRootProps {\n readonly children: ReactNode\n}\n\nexport const EditorRoot: FC<EditorRootProps> = ({ children }) => children as any\n\nexport type EditorContentProps = EditorProviderProps & {\n readonly children?: ReactNode\n readonly className?: string\n readonly initialContent?: any\n}\n\nexport const EditorContent = forwardRef<HTMLDivElement, EditorContentProps>(\n ({ className, children, initialContent, content, ...rest }, ref) => {\n const effectiveContent = content ?? initialContent\n return (\n <div ref={ref} className={className}>\n <EditorProvider {...rest} content={effectiveContent}>\n {children}\n </EditorProvider>\n </div>\n )\n }\n)\n\nEditorContent.displayName = \"EditorContent\"\n","import { useCurrentEditor } from \"@tiptap/react\";\nimport { BubbleMenu as BubbleMenuReact } from \"@tiptap/react/menus\";\nimport type { ReactNode } from \"react\";\n\nexport interface EditorBubbleProps {\n readonly className?: string;\n readonly children: ReactNode;\n readonly options?: Record<string, unknown>;\n}\n\nexport function EditorBubble({ className, children, options }: EditorBubbleProps) {\n const { editor } = useCurrentEditor();\n if (!editor) return null;\n\n return (\n <BubbleMenuReact editor={editor} options={options}>\n <div className={className}>{children}</div>\n </BubbleMenuReact>\n );\n}\n","import { forwardRef, isValidElement, cloneElement } from \"react\"\nimport type { ComponentPropsWithoutRef, ReactElement, ReactNode } from \"react\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport type { Editor as TiptapEditor } from \"@tiptap/react\"\n\ninterface EditorBubbleItemProps {\n readonly children: ReactNode\n readonly asChild?: boolean\n readonly onSelect?: (editor: TiptapEditor) => void\n}\n\nexport const EditorBubbleItem = forwardRef<\n HTMLDivElement,\n EditorBubbleItemProps & Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\">\n>(({ children, asChild, onSelect, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n\n if (!editor) return null\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault()\n onSelect?.(editor)\n }\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<any>\n const childOnClick = (child.props as any)?.onClick as\n | ((e: any) => void)\n | undefined\n const mergedOnClick = (e: any) => {\n childOnClick?.(e)\n if (!e?.defaultPrevented) onSelect?.(editor)\n }\n\n return cloneElement(child, {\n ...rest,\n ref: (child as any).ref ?? ref,\n onClick: mergedOnClick,\n })\n }\n\n return (\n <div ref={ref} {...rest} onClick={handleClick}>\n {children}\n </div>\n )\n})\n\nEditorBubbleItem.displayName = \"EditorBubbleItem\"\n\nexport default EditorBubbleItem\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\nimport type { ComponentPropsWithoutRef, FC, ReactNode } from \"react\"\n\ntype Range = { from: number; to: number }\n\ntype Ctx = {\n query: string\n setQuery: (q: string) => void\n range: Range | null\n setRange: (r: Range | null) => void\n}\n\nconst EditorCommandContext = createContext<Ctx | null>(null)\n\nexport function useEditorCommand() {\n const ctx = useContext(EditorCommandContext)\n if (!ctx)\n throw new Error(\"useEditorCommand must be used within <EditorCommand>\")\n return ctx\n}\n\nexport interface EditorCommandProps extends ComponentPropsWithoutRef<\"div\"> {\n readonly children?: ReactNode\n}\n\nexport const EditorCommand = forwardRef<HTMLDivElement, EditorCommandProps>(\n ({ className, children, ...rest }, ref) => {\n const [query, setQuery] = useState(\"\")\n const [range, setRange] = useState<Range | null>(null)\n\n const value = useMemo<Ctx>(\n () => ({ query, setQuery, range, setRange }),\n [query, range]\n )\n\n return (\n <EditorCommandContext.Provider value={value}>\n <div\n ref={ref}\n id=\"nph-slash-command\"\n className={[\"nph-command\", className].filter(Boolean).join(\" \")}\n onKeyDown={(e) => {\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(e.key)) {\n e.stopPropagation()\n }\n }}\n {...rest}\n >\n <input\n style={{ display: \"none\" }}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n {children}\n </div>\n </EditorCommandContext.Provider>\n )\n }\n)\nEditorCommand.displayName = \"EditorCommand\"\n\nexport const EditorCommandList = forwardRef<\n HTMLUListElement,\n ComponentPropsWithoutRef<\"ul\">\n>(({ className, children, ...rest }, ref) => (\n <ul\n ref={ref}\n role=\"listbox\"\n className={[\"nph-command__list\", className].filter(Boolean).join(\" \")}\n {...rest}\n >\n {children}\n </ul>\n))\nEditorCommandList.displayName = \"EditorCommandList\"\n\ninterface EditorCommandOutProps {\n readonly query: string\n readonly range: Range\n}\n\nexport const EditorCommandOut: FC<EditorCommandOutProps> = ({\n query,\n range,\n}) => {\n const ctx = useContext(EditorCommandContext)\n\n useEffect(() => {\n ctx?.setQuery(query)\n }, [query])\n\n useEffect(() => {\n ctx?.setRange(range)\n }, [range])\n\n useEffect(() => {\n const navigationKeys = [\"ArrowUp\", \"ArrowDown\", \"Enter\"]\n const onKeyDown = (e: KeyboardEvent) => {\n if (navigationKeys.includes(e.key)) {\n e.preventDefault()\n const commandRef = document.querySelector(\"#nph-slash-command\")\n if (commandRef)\n commandRef.dispatchEvent(\n new KeyboardEvent(\"keydown\", {\n key: e.key,\n cancelable: true,\n bubbles: true,\n })\n )\n return false\n }\n }\n document.addEventListener(\"keydown\", onKeyDown)\n return () => document.removeEventListener(\"keydown\", onKeyDown)\n }, [])\n\n return null\n}\n","import { forwardRef } from \"react\";\nimport type { ComponentPropsWithoutRef } from \"react\";\n\nexport interface EditorCommandItemProps extends ComponentPropsWithoutRef<\"li\"> {\n active?: boolean;\n onSelect?: () => void;\n}\n\nexport const EditorCommandItem = forwardRef<HTMLLIElement, EditorCommandItemProps>(\n ({ className, active, onSelect, children, ...rest }, ref) => (\n <li\n ref={ref}\n role=\"option\"\n aria-selected={!!active}\n className={[\n \"nph-command__item\",\n active ? \"is-active\" : undefined,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n onMouseDown={(e) => e.preventDefault()}\n onClick={onSelect}\n {...rest}\n >\n {children}\n </li>\n ),\n);\n\nEditorCommandItem.displayName = \"EditorCommandItem\";\n\nexport default EditorCommandItem;\n\n","import PlaceholderExt from \"@tiptap/extension-placeholder\"\n\nexport { StarterKit } from \"@tiptap/starter-kit\"\n\n// Configured Placeholder with helpful defaults\nexport const Placeholder = PlaceholderExt.configure({\n placeholder: ({ node }: any) => {\n if (node.type.name === \"heading\") {\n return `Heading ${node.attrs.level}`\n }\n return \"Press '/' for commands\"\n },\n includeChildren: true,\n})\n\n// Minimal default bundle\nexport const defaultExtensions = [Placeholder]\n"],"mappings":"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","names":["useCurrentEditor","jsx","forwardRef","useCurrentEditor","jsx","forwardRef","jsx","forwardRef","jsx","forwardRef","jsx"]}
|