@agent-native/toolkit 0.4.10 → 0.5.1
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/README.md +17 -6
- package/dist/collab-ui/agent-identity.d.ts +9 -0
- package/dist/collab-ui/agent-identity.d.ts.map +1 -0
- package/dist/collab-ui/agent-identity.js +9 -0
- package/dist/collab-ui/agent-identity.js.map +1 -0
- package/dist/collab-ui/index.d.ts +2 -0
- package/dist/collab-ui/index.d.ts.map +1 -1
- package/dist/collab-ui/index.js +2 -0
- package/dist/collab-ui/index.js.map +1 -1
- package/dist/collab-ui/lead-client.d.ts +3 -0
- package/dist/collab-ui/lead-client.d.ts.map +1 -0
- package/dist/collab-ui/lead-client.js +29 -0
- package/dist/collab-ui/lead-client.js.map +1 -0
- package/dist/context-ui/ContextMeter.d.ts +10 -0
- package/dist/context-ui/ContextMeter.d.ts.map +1 -0
- package/dist/context-ui/ContextMeter.js +20 -0
- package/dist/context-ui/ContextMeter.js.map +1 -0
- package/dist/context-ui/ContextSegmentRow.d.ts +14 -0
- package/dist/context-ui/ContextSegmentRow.d.ts.map +1 -0
- package/dist/context-ui/ContextSegmentRow.js +25 -0
- package/dist/context-ui/ContextSegmentRow.js.map +1 -0
- package/dist/context-ui/ContextTreemap.d.ts +7 -0
- package/dist/context-ui/ContextTreemap.d.ts.map +1 -0
- package/dist/context-ui/ContextTreemap.js +55 -0
- package/dist/context-ui/ContextTreemap.js.map +1 -0
- package/dist/context-ui/ContextXRayPanel.d.ts +13 -0
- package/dist/context-ui/ContextXRayPanel.d.ts.map +1 -0
- package/dist/context-ui/ContextXRayPanel.js +120 -0
- package/dist/context-ui/ContextXRayPanel.js.map +1 -0
- package/dist/context-ui/format.d.ts +6 -0
- package/dist/context-ui/format.d.ts.map +1 -0
- package/dist/context-ui/format.js +58 -0
- package/dist/context-ui/format.js.map +1 -0
- package/dist/context-ui/index.d.ts +7 -0
- package/dist/context-ui/index.d.ts.map +1 -0
- package/dist/context-ui/index.js +6 -0
- package/dist/context-ui/index.js.map +1 -0
- package/dist/context-ui/types.d.ts +39 -0
- package/dist/context-ui/types.d.ts.map +1 -0
- package/dist/context-ui/types.js +2 -0
- package/dist/context-ui/types.js.map +1 -0
- package/dist/design-tweaks/index.d.ts +2 -0
- package/dist/design-tweaks/index.d.ts.map +1 -0
- package/dist/design-tweaks/index.js +2 -0
- package/dist/design-tweaks/index.js.map +1 -0
- package/dist/design-tweaks/visual-style-controls.d.ts +90 -0
- package/dist/design-tweaks/visual-style-controls.d.ts.map +1 -0
- package/dist/design-tweaks/visual-style-controls.js +499 -0
- package/dist/design-tweaks/visual-style-controls.js.map +1 -0
- package/dist/editor/BubbleToolbar.d.ts +37 -0
- package/dist/editor/BubbleToolbar.d.ts.map +1 -0
- package/dist/editor/BubbleToolbar.js +171 -0
- package/dist/editor/BubbleToolbar.js.map +1 -0
- package/dist/editor/CodeBlockNode.d.ts +49 -0
- package/dist/editor/CodeBlockNode.d.ts.map +1 -0
- package/dist/editor/CodeBlockNode.js +127 -0
- package/dist/editor/CodeBlockNode.js.map +1 -0
- package/dist/editor/DragHandle.d.ts +97 -0
- package/dist/editor/DragHandle.d.ts.map +1 -0
- package/dist/editor/DragHandle.js +1066 -0
- package/dist/editor/DragHandle.js.map +1 -0
- package/dist/editor/DragHandle.spec.d.ts +2 -0
- package/dist/editor/DragHandle.spec.d.ts.map +1 -0
- package/dist/editor/DragHandle.spec.js +407 -0
- package/dist/editor/DragHandle.spec.js.map +1 -0
- package/dist/editor/ImageExtension.d.ts +63 -0
- package/dist/editor/ImageExtension.d.ts.map +1 -0
- package/dist/editor/ImageExtension.js +243 -0
- package/dist/editor/ImageExtension.js.map +1 -0
- package/dist/editor/ImageExtension.roundtrip.spec.d.ts +2 -0
- package/dist/editor/ImageExtension.roundtrip.spec.d.ts.map +1 -0
- package/dist/editor/ImageExtension.roundtrip.spec.js +103 -0
- package/dist/editor/ImageExtension.roundtrip.spec.js.map +1 -0
- package/dist/editor/RichMarkdownEditor.collab.spec.d.ts +2 -0
- package/dist/editor/RichMarkdownEditor.collab.spec.d.ts.map +1 -0
- package/dist/editor/RichMarkdownEditor.collab.spec.js +65 -0
- package/dist/editor/RichMarkdownEditor.collab.spec.js.map +1 -0
- package/dist/editor/RichMarkdownEditor.d.ts +52 -0
- package/dist/editor/RichMarkdownEditor.d.ts.map +1 -0
- package/dist/editor/RichMarkdownEditor.js +38 -0
- package/dist/editor/RichMarkdownEditor.js.map +1 -0
- package/dist/editor/RichMarkdownEditor.roundtrip.spec.d.ts +2 -0
- package/dist/editor/RichMarkdownEditor.roundtrip.spec.d.ts.map +1 -0
- package/dist/editor/RichMarkdownEditor.roundtrip.spec.js +186 -0
- package/dist/editor/RichMarkdownEditor.roundtrip.spec.js.map +1 -0
- package/dist/editor/RunId.d.ts +28 -0
- package/dist/editor/RunId.d.ts.map +1 -0
- package/dist/editor/RunId.js +60 -0
- package/dist/editor/RunId.js.map +1 -0
- package/dist/editor/SharedRichEditor.d.ts +110 -0
- package/dist/editor/SharedRichEditor.d.ts.map +1 -0
- package/dist/editor/SharedRichEditor.js +144 -0
- package/dist/editor/SharedRichEditor.js.map +1 -0
- package/dist/editor/SlashCommandMenu.d.ts +41 -0
- package/dist/editor/SlashCommandMenu.d.ts.map +1 -0
- package/dist/editor/SlashCommandMenu.js +221 -0
- package/dist/editor/SlashCommandMenu.js.map +1 -0
- package/dist/editor/disableHistory.spec.d.ts +2 -0
- package/dist/editor/disableHistory.spec.d.ts.map +1 -0
- package/dist/editor/disableHistory.spec.js +73 -0
- package/dist/editor/disableHistory.spec.js.map +1 -0
- package/dist/editor/extensions.d.ts +178 -0
- package/dist/editor/extensions.d.ts.map +1 -0
- package/dist/editor/extensions.js +224 -0
- package/dist/editor/extensions.js.map +1 -0
- package/dist/editor/gfmDoc.d.ts +24 -0
- package/dist/editor/gfmDoc.d.ts.map +1 -0
- package/dist/editor/gfmDoc.js +83 -0
- package/dist/editor/gfmDoc.js.map +1 -0
- package/dist/editor/gfmDoc.spec.d.ts +2 -0
- package/dist/editor/gfmDoc.spec.d.ts.map +1 -0
- package/dist/editor/gfmDoc.spec.js +194 -0
- package/dist/editor/gfmDoc.spec.js.map +1 -0
- package/dist/editor/index.d.ts +14 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +13 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/structuralReorderUndo.spec.d.ts +2 -0
- package/dist/editor/structuralReorderUndo.spec.d.ts.map +1 -0
- package/dist/editor/structuralReorderUndo.spec.js +120 -0
- package/dist/editor/structuralReorderUndo.spec.js.map +1 -0
- package/dist/editor/surgical-apply.d.ts +66 -0
- package/dist/editor/surgical-apply.d.ts.map +1 -0
- package/dist/editor/surgical-apply.js +147 -0
- package/dist/editor/surgical-apply.js.map +1 -0
- package/dist/editor/surgical-apply.spec.d.ts +2 -0
- package/dist/editor/surgical-apply.spec.d.ts.map +1 -0
- package/dist/editor/surgical-apply.spec.js +257 -0
- package/dist/editor/surgical-apply.spec.js.map +1 -0
- package/dist/editor/useCollabReconcile.concurrent.spec.d.ts +2 -0
- package/dist/editor/useCollabReconcile.concurrent.spec.d.ts.map +1 -0
- package/dist/editor/useCollabReconcile.concurrent.spec.js +329 -0
- package/dist/editor/useCollabReconcile.concurrent.spec.js.map +1 -0
- package/dist/editor/useCollabReconcile.d.ts +110 -0
- package/dist/editor/useCollabReconcile.d.ts.map +1 -0
- package/dist/editor/useCollabReconcile.idempotent.spec.d.ts +2 -0
- package/dist/editor/useCollabReconcile.idempotent.spec.d.ts.map +1 -0
- package/dist/editor/useCollabReconcile.idempotent.spec.js +248 -0
- package/dist/editor/useCollabReconcile.idempotent.spec.js.map +1 -0
- package/dist/editor/useCollabReconcile.js +440 -0
- package/dist/editor/useCollabReconcile.js.map +1 -0
- package/dist/editor.css +510 -0
- package/migration-manifest.json +4 -0
- package/package.json +65 -9
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { cn } from "../utils.js";
|
|
5
|
+
/**
|
|
6
|
+
* Builds the default selection-toolbar items (Plan's current set): bold,
|
|
7
|
+
* italic, strike, code, headings 1-3, and a link toggle. `toggleLink` is
|
|
8
|
+
* supplied by the toolbar so the link-editor input can be opened.
|
|
9
|
+
*/
|
|
10
|
+
export function buildDefaultBubbleItems(editor, toggleLink) {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
label: "B",
|
|
14
|
+
title: "Bold",
|
|
15
|
+
action: () => editor.chain().focus().toggleBold().run(),
|
|
16
|
+
isActive: () => editor.isActive("bold"),
|
|
17
|
+
style: { fontWeight: 700 },
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
label: "I",
|
|
21
|
+
title: "Italic",
|
|
22
|
+
action: () => editor.chain().focus().toggleItalic().run(),
|
|
23
|
+
isActive: () => editor.isActive("italic"),
|
|
24
|
+
style: { fontStyle: "italic" },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
label: "S",
|
|
28
|
+
title: "Strikethrough",
|
|
29
|
+
action: () => editor.chain().focus().toggleStrike().run(),
|
|
30
|
+
isActive: () => editor.isActive("strike"),
|
|
31
|
+
style: { textDecoration: "line-through" },
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: "<>",
|
|
35
|
+
title: "Code",
|
|
36
|
+
action: () => editor.chain().focus().toggleCode().run(),
|
|
37
|
+
isActive: () => editor.isActive("code"),
|
|
38
|
+
style: { fontFamily: "monospace", fontSize: 11 },
|
|
39
|
+
},
|
|
40
|
+
{ type: "divider" },
|
|
41
|
+
{
|
|
42
|
+
label: "H1",
|
|
43
|
+
title: "Heading 1",
|
|
44
|
+
action: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
|
|
45
|
+
isActive: () => editor.isActive("heading", { level: 1 }),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "H2",
|
|
49
|
+
title: "Heading 2",
|
|
50
|
+
action: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
51
|
+
isActive: () => editor.isActive("heading", { level: 2 }),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
label: "H3",
|
|
55
|
+
title: "Heading 3",
|
|
56
|
+
action: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
|
|
57
|
+
isActive: () => editor.isActive("heading", { level: 3 }),
|
|
58
|
+
},
|
|
59
|
+
{ type: "divider" },
|
|
60
|
+
{
|
|
61
|
+
label: "Link",
|
|
62
|
+
title: "Link",
|
|
63
|
+
action: toggleLink,
|
|
64
|
+
isActive: () => editor.isActive("link"),
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The shared floating selection toolbar. Tracks the current text selection and
|
|
70
|
+
* positions a fixed toolbar above it, with an inline link editor. Extracted
|
|
71
|
+
* from the inline plan toolbar so embedders share one implementation; apps swap
|
|
72
|
+
* the item set via `buildItems`.
|
|
73
|
+
*/
|
|
74
|
+
export function BubbleToolbar({ editor, buildItems = buildDefaultBubbleItems, }) {
|
|
75
|
+
const [visible, setVisible] = useState(false);
|
|
76
|
+
const [coords, setCoords] = useState({ top: 0, left: 0 });
|
|
77
|
+
const [showLinkInput, setShowLinkInput] = useState(false);
|
|
78
|
+
const [linkUrl, setLinkUrl] = useState("");
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const update = () => {
|
|
81
|
+
const selectionState = editor.state.selection;
|
|
82
|
+
const { from, to } = selectionState;
|
|
83
|
+
const selection = window.getSelection();
|
|
84
|
+
const selectionInsideEditor = !!selection?.anchorNode &&
|
|
85
|
+
!!selection.focusNode &&
|
|
86
|
+
editor.view.dom.contains(selection.anchorNode) &&
|
|
87
|
+
editor.view.dom.contains(selection.focusNode);
|
|
88
|
+
if (!(selectionState instanceof TextSelection) ||
|
|
89
|
+
from === to ||
|
|
90
|
+
!selectionInsideEditor) {
|
|
91
|
+
setVisible(false);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!selection || selection.rangeCount === 0) {
|
|
95
|
+
setVisible(false);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const rect = selection.getRangeAt(0).getBoundingClientRect();
|
|
99
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
100
|
+
setVisible(false);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
setCoords({
|
|
104
|
+
top: rect.top - 8,
|
|
105
|
+
left: rect.left + rect.width / 2,
|
|
106
|
+
});
|
|
107
|
+
setVisible(true);
|
|
108
|
+
};
|
|
109
|
+
editor.on("selectionUpdate", update);
|
|
110
|
+
editor.on("transaction", update);
|
|
111
|
+
document.addEventListener("selectionchange", update);
|
|
112
|
+
const onBlur = () => {
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
if (!editor.isFocused)
|
|
115
|
+
setVisible(false);
|
|
116
|
+
}, 140);
|
|
117
|
+
};
|
|
118
|
+
editor.on("blur", onBlur);
|
|
119
|
+
return () => {
|
|
120
|
+
editor.off("selectionUpdate", update);
|
|
121
|
+
editor.off("transaction", update);
|
|
122
|
+
document.removeEventListener("selectionchange", update);
|
|
123
|
+
editor.off("blur", onBlur);
|
|
124
|
+
};
|
|
125
|
+
}, [editor]);
|
|
126
|
+
const handleSetLink = () => {
|
|
127
|
+
if (linkUrl.trim()) {
|
|
128
|
+
editor
|
|
129
|
+
.chain()
|
|
130
|
+
.focus()
|
|
131
|
+
.extendMarkRange("link")
|
|
132
|
+
.setLink({ href: linkUrl.trim() })
|
|
133
|
+
.run();
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
137
|
+
}
|
|
138
|
+
setShowLinkInput(false);
|
|
139
|
+
setLinkUrl("");
|
|
140
|
+
};
|
|
141
|
+
const toggleLink = () => {
|
|
142
|
+
if (editor.isActive("link")) {
|
|
143
|
+
editor.chain().focus().unsetLink().run();
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
setLinkUrl(editor.getAttributes("link").href || "");
|
|
147
|
+
setShowLinkInput(true);
|
|
148
|
+
};
|
|
149
|
+
const items = buildItems(editor, toggleLink);
|
|
150
|
+
if (!visible)
|
|
151
|
+
return null;
|
|
152
|
+
return (_jsx("div", { className: "an-rich-md-bubble-toolbar", style: {
|
|
153
|
+
position: "fixed",
|
|
154
|
+
top: coords.top,
|
|
155
|
+
left: coords.left,
|
|
156
|
+
transform: "translate(-50%, -100%)",
|
|
157
|
+
}, onMouseDown: (event) => event.preventDefault(), "data-plan-interactive": true, children: showLinkInput ? (_jsxs("div", { className: "an-rich-md-link-editor", children: [_jsx("input", { autoFocus: true, type: "url", placeholder: "Paste link...", value: linkUrl, onChange: (event) => setLinkUrl(event.target.value), onKeyDown: (event) => {
|
|
158
|
+
if (event.key === "Enter")
|
|
159
|
+
handleSetLink();
|
|
160
|
+
if (event.key === "Escape") {
|
|
161
|
+
setShowLinkInput(false);
|
|
162
|
+
setLinkUrl("");
|
|
163
|
+
}
|
|
164
|
+
} }), _jsx("button", { type: "button", onClick: handleSetLink, children: "Apply" })] })) : (_jsx("div", { className: "an-rich-md-bubble-items", children: items.map((item, index) => {
|
|
165
|
+
if ("type" in item) {
|
|
166
|
+
return (_jsx("span", { className: "an-rich-md-bubble-divider" }, `divider-${index}`));
|
|
167
|
+
}
|
|
168
|
+
return (_jsx("button", { type: "button", title: item.title, className: cn("an-rich-md-bubble-button", item.isActive() && "an-rich-md-bubble-button--active"), style: item.style, onClick: item.action, children: item.label }, item.title));
|
|
169
|
+
}) })) }));
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=BubbleToolbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BubbleToolbar.js","sourceRoot":"","sources":["../../src/editor/BubbleToolbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Node as TiptapNode } from "@tiptap/core";
|
|
2
|
+
import type { createLowlight } from "lowlight";
|
|
3
|
+
/**
|
|
4
|
+
* A selectable language for the code-block picker. `value === null` is the
|
|
5
|
+
* "Auto" sentinel: the block stores no language and the lowlight plugin
|
|
6
|
+
* auto-detects (biased toward the editor's registered, web-leaning grammar
|
|
7
|
+
* set). Keeping it first makes Auto the default, matching how plans skew toward
|
|
8
|
+
* JS/TS/JSON without the author having to choose.
|
|
9
|
+
*/
|
|
10
|
+
export interface CodeLanguageOption {
|
|
11
|
+
value: string | null;
|
|
12
|
+
label: string;
|
|
13
|
+
}
|
|
14
|
+
/** Default picker list — Auto first, then the web-leaning grammars plans use. */
|
|
15
|
+
export declare const DEFAULT_CODE_LANGUAGES: CodeLanguageOption[];
|
|
16
|
+
/** Class hooks so each app themes the shared node with its own palette. */
|
|
17
|
+
export interface CodeBlockClassNames {
|
|
18
|
+
wrapper: string;
|
|
19
|
+
header: string;
|
|
20
|
+
langButton: string;
|
|
21
|
+
langButtonReadonly: string;
|
|
22
|
+
picker: string;
|
|
23
|
+
search: string;
|
|
24
|
+
list: string;
|
|
25
|
+
option: string;
|
|
26
|
+
optionActive: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CreateCodeBlockNodeOptions {
|
|
29
|
+
/** Lowlight instance backing syntax highlighting (same one the app registers). */
|
|
30
|
+
lowlight: ReturnType<typeof createLowlight>;
|
|
31
|
+
/** Picker languages. Defaults to {@link DEFAULT_CODE_LANGUAGES} (Auto first). */
|
|
32
|
+
languages?: CodeLanguageOption[];
|
|
33
|
+
/** Class hooks for per-app theming. Defaults to the shared `an-code-block__*`. */
|
|
34
|
+
classNames?: Partial<CodeBlockClassNames>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The shared Notion-style code block: {@link CodeBlockLowlight} (so fenced
|
|
38
|
+
* markdown round-trips byte-identically — the node name and `language` attr are
|
|
39
|
+
* unchanged) plus a React node view that adds a language picker header instead
|
|
40
|
+
* of a bare highlighted `<pre>`. "Auto" stores no language and the lowlight
|
|
41
|
+
* plugin auto-detects.
|
|
42
|
+
*
|
|
43
|
+
* Lifted from the Content editor's bespoke code block so Plans (and any app
|
|
44
|
+
* opting into `features.codeBlock`) share one implementation. Theming is fully
|
|
45
|
+
* class-driven via {@link CreateCodeBlockNodeOptions.classNames}, so each app
|
|
46
|
+
* maps the hooks onto its own palette.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createCodeBlockNode({ lowlight, languages, classNames, }: CreateCodeBlockNodeOptions): TiptapNode;
|
|
49
|
+
//# sourceMappingURL=CodeBlockNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlockNode.d.ts","sourceRoot":"","sources":["../../src/editor/CodeBlockNode.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAQvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM/C;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,EAkBtD,CAAC;AAEF,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAcD,MAAM,WAAW,0BAA0B;IACzC,kFAAkF;IAClF,QAAQ,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC5C,iFAAiF;IACjF,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACjC,kFAAkF;IAClF,UAAU,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC3C;AA2HD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,SAAkC,EAClC,UAAU,GACX,EAAE,0BAA0B,GAAG,UAAU,CAkCzC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconCheck, IconChevronDown } from "@tabler/icons-react";
|
|
3
|
+
import { CodeBlockLowlight } from "@tiptap/extension-code-block-lowlight";
|
|
4
|
+
import { NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer, } from "@tiptap/react";
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
6
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
|
|
7
|
+
import { cn } from "../utils.js";
|
|
8
|
+
/** Default picker list — Auto first, then the web-leaning grammars plans use. */
|
|
9
|
+
export const DEFAULT_CODE_LANGUAGES = [
|
|
10
|
+
{ value: null, label: "Auto" },
|
|
11
|
+
{ value: "typescript", label: "TypeScript" },
|
|
12
|
+
{ value: "javascript", label: "JavaScript" },
|
|
13
|
+
{ value: "tsx", label: "TSX" },
|
|
14
|
+
{ value: "jsx", label: "JSX" },
|
|
15
|
+
{ value: "json", label: "JSON" },
|
|
16
|
+
{ value: "html", label: "HTML" },
|
|
17
|
+
{ value: "css", label: "CSS" },
|
|
18
|
+
{ value: "bash", label: "Bash" },
|
|
19
|
+
{ value: "python", label: "Python" },
|
|
20
|
+
{ value: "sql", label: "SQL" },
|
|
21
|
+
{ value: "yaml", label: "YAML" },
|
|
22
|
+
{ value: "markdown", label: "Markdown" },
|
|
23
|
+
{ value: "graphql", label: "GraphQL" },
|
|
24
|
+
{ value: "go", label: "Go" },
|
|
25
|
+
{ value: "rust", label: "Rust" },
|
|
26
|
+
{ value: "diff", label: "Diff" },
|
|
27
|
+
];
|
|
28
|
+
const DEFAULT_CLASS_NAMES = {
|
|
29
|
+
wrapper: "an-code-block",
|
|
30
|
+
header: "an-code-block__header",
|
|
31
|
+
langButton: "an-code-block__lang",
|
|
32
|
+
langButtonReadonly: "an-code-block__lang--readonly",
|
|
33
|
+
picker: "an-code-block__picker",
|
|
34
|
+
search: "an-code-block__search",
|
|
35
|
+
list: "an-code-block__list",
|
|
36
|
+
option: "an-code-block__option",
|
|
37
|
+
optionActive: "is-active",
|
|
38
|
+
};
|
|
39
|
+
function optionLabel(language, languages) {
|
|
40
|
+
if (!language)
|
|
41
|
+
return languages[0]?.label ?? "Auto";
|
|
42
|
+
const match = languages.find((option) => option.value === language);
|
|
43
|
+
return match?.label ?? language;
|
|
44
|
+
}
|
|
45
|
+
function CodeBlockView({ node, updateAttributes, editor, extension, }) {
|
|
46
|
+
const options = extension.options;
|
|
47
|
+
const languages = options.languagePickerOptions;
|
|
48
|
+
const classNames = options.codeBlockClassNames;
|
|
49
|
+
const [open, setOpen] = useState(false);
|
|
50
|
+
const [filter, setFilter] = useState("");
|
|
51
|
+
const isEditable = editor.isEditable;
|
|
52
|
+
const current = node.attrs.language || null;
|
|
53
|
+
const label = optionLabel(current, languages);
|
|
54
|
+
const filtered = useMemo(() => {
|
|
55
|
+
const query = filter.trim().toLowerCase();
|
|
56
|
+
if (!query)
|
|
57
|
+
return languages;
|
|
58
|
+
return languages.filter((option) => option.label.toLowerCase().includes(query));
|
|
59
|
+
}, [filter, languages]);
|
|
60
|
+
const select = (value) => {
|
|
61
|
+
// Store `""` for Auto so tiptap-markdown emits a bare fence (no language),
|
|
62
|
+
// matching the auto-detect read path.
|
|
63
|
+
updateAttributes({ language: value ?? "" });
|
|
64
|
+
setFilter("");
|
|
65
|
+
setOpen(false);
|
|
66
|
+
};
|
|
67
|
+
return (_jsxs(NodeViewWrapper, { className: classNames.wrapper, children: [_jsx("div", { className: classNames.header, contentEditable: false, children: isEditable ? (_jsxs(Popover, { open: open, onOpenChange: (next) => {
|
|
68
|
+
setOpen(next);
|
|
69
|
+
if (!next)
|
|
70
|
+
setFilter("");
|
|
71
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: classNames.langButton, children: [label, _jsx(IconChevronDown, { className: "size-3" })] }) }), _jsxs(PopoverContent, { align: "start", side: "bottom", className: "w-52 p-0", children: [_jsx("input", { autoFocus: true, type: "text", value: filter, onChange: (event) => setFilter(event.target.value), onKeyDown: (event) => {
|
|
72
|
+
if (event.key === "Enter" && filtered.length > 0) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
select(filtered[0].value);
|
|
75
|
+
}
|
|
76
|
+
}, placeholder: "Search languages\u2026", className: classNames.search }), _jsx("div", { className: classNames.list, children: filtered.map((option) => {
|
|
77
|
+
const active = option.value === current || (!option.value && !current);
|
|
78
|
+
return (_jsxs("button", { type: "button", className: cn(classNames.option, active && classNames.optionActive), onClick: () => select(option.value), children: [option.label, active && _jsx(IconCheck, { className: "size-3.5" })] }, option.value ?? "auto"));
|
|
79
|
+
}) })] })] })) : (label && (_jsx("span", { className: cn(classNames.langButton, classNames.langButtonReadonly), children: label }))) }), _jsx("pre", { children: _jsx(NodeViewContent, { as: "code" }) })] }));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The shared Notion-style code block: {@link CodeBlockLowlight} (so fenced
|
|
83
|
+
* markdown round-trips byte-identically — the node name and `language` attr are
|
|
84
|
+
* unchanged) plus a React node view that adds a language picker header instead
|
|
85
|
+
* of a bare highlighted `<pre>`. "Auto" stores no language and the lowlight
|
|
86
|
+
* plugin auto-detects.
|
|
87
|
+
*
|
|
88
|
+
* Lifted from the Content editor's bespoke code block so Plans (and any app
|
|
89
|
+
* opting into `features.codeBlock`) share one implementation. Theming is fully
|
|
90
|
+
* class-driven via {@link CreateCodeBlockNodeOptions.classNames}, so each app
|
|
91
|
+
* maps the hooks onto its own palette.
|
|
92
|
+
*/
|
|
93
|
+
export function createCodeBlockNode({ lowlight, languages = DEFAULT_CODE_LANGUAGES, classNames, }) {
|
|
94
|
+
const resolvedClassNames = {
|
|
95
|
+
...DEFAULT_CLASS_NAMES,
|
|
96
|
+
...(classNames ?? {}),
|
|
97
|
+
};
|
|
98
|
+
return CodeBlockLowlight.extend({
|
|
99
|
+
addOptions() {
|
|
100
|
+
return {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
102
|
+
...this.parent(),
|
|
103
|
+
languagePickerOptions: languages,
|
|
104
|
+
codeBlockClassNames: resolvedClassNames,
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
addNodeView() {
|
|
108
|
+
return ReactNodeViewRenderer(CodeBlockView);
|
|
109
|
+
},
|
|
110
|
+
addKeyboardShortcuts() {
|
|
111
|
+
return {
|
|
112
|
+
...this.parent?.(),
|
|
113
|
+
Tab: ({ editor }) => {
|
|
114
|
+
if (editor.isActive(this.name)) {
|
|
115
|
+
editor.commands.insertContent("\t");
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
}).configure({
|
|
123
|
+
lowlight,
|
|
124
|
+
defaultLanguage: null,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=CodeBlockNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlockNode.js","sourceRoot":"","sources":["../../src/editor/CodeBlockNode.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Extension } from "@tiptap/core";
|
|
2
|
+
import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
|
|
3
|
+
import { type EditorView } from "@tiptap/pm/view";
|
|
4
|
+
/**
|
|
5
|
+
* Default editor-wrapper CSS selector the drag handle scopes itself to.
|
|
6
|
+
*
|
|
7
|
+
* The handle, the drop indicator, and the `position: relative` anchor are all
|
|
8
|
+
* appended to / measured against the closest ancestor matching this selector.
|
|
9
|
+
* Content's editor wraps its ProseMirror DOM in a `.visual-editor-wrapper`
|
|
10
|
+
* element, so that is the historical default. Other apps (e.g. the plan editor)
|
|
11
|
+
* pass their own wrapper selector via {@link DragHandleOptions.wrapperSelector}.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR = ".visual-editor-wrapper";
|
|
14
|
+
export interface DragHandleOptions {
|
|
15
|
+
/**
|
|
16
|
+
* CSS selector for the editor wrapper element the handle is anchored to.
|
|
17
|
+
*
|
|
18
|
+
* Must match an ancestor of the ProseMirror editor DOM. The wrapper gets
|
|
19
|
+
* `position: relative` so the absolutely-positioned grip and drop indicator
|
|
20
|
+
* can be placed relative to it. Defaults to
|
|
21
|
+
* {@link DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR} so Content keeps working
|
|
22
|
+
* unchanged.
|
|
23
|
+
*/
|
|
24
|
+
wrapperSelector: string;
|
|
25
|
+
/**
|
|
26
|
+
* Optional source-side payload for a cross-editor block move. The editor doc
|
|
27
|
+
* carries ProseMirror node content, but app-owned side-map data (for example a
|
|
28
|
+
* plan `diagram` block's HTML/CSS) can live outside the doc; this lets the
|
|
29
|
+
* host carry that data to the receiving editor before the node is inserted.
|
|
30
|
+
*/
|
|
31
|
+
getDragTransferData?: (context: {
|
|
32
|
+
view: EditorView;
|
|
33
|
+
node: ProseMirrorNode;
|
|
34
|
+
pos: number;
|
|
35
|
+
}) => unknown;
|
|
36
|
+
/**
|
|
37
|
+
* Optional target-side receiver for cross-editor transfer data. Called before
|
|
38
|
+
* the node is inserted into the target editor so the target's serializer can
|
|
39
|
+
* resolve app-owned data during the synchronous ProseMirror update.
|
|
40
|
+
*/
|
|
41
|
+
receiveDragTransferData?: (data: unknown, context: {
|
|
42
|
+
view: EditorView;
|
|
43
|
+
node: ProseMirrorNode;
|
|
44
|
+
pos: number;
|
|
45
|
+
sourceView: EditorView;
|
|
46
|
+
}) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Optional host-level drop handler for document-specific structure changes.
|
|
49
|
+
* Returning true tells the shared drag handle that the host fully handled the
|
|
50
|
+
* move and no ProseMirror insert/delete should run. This is used for
|
|
51
|
+
* Notion-style side drops where dropping a block to the left/right creates or
|
|
52
|
+
* inserts into a column layout rather than inserting into the target editor.
|
|
53
|
+
*/
|
|
54
|
+
handleDrop?: (data: unknown, context: DragHandleDropContext) => boolean;
|
|
55
|
+
}
|
|
56
|
+
export type DragHandleDropPlacement = "before" | "after" | "left" | "right";
|
|
57
|
+
export type DragHandleDropContext = {
|
|
58
|
+
view: EditorView;
|
|
59
|
+
sourceView: EditorView;
|
|
60
|
+
sourceNode: ProseMirrorNode;
|
|
61
|
+
sourcePos: number;
|
|
62
|
+
sourceNodeSize: number;
|
|
63
|
+
targetNode: ProseMirrorNode;
|
|
64
|
+
targetPos: number;
|
|
65
|
+
targetNodeSize: number;
|
|
66
|
+
insertPos: number;
|
|
67
|
+
placement: DragHandleDropPlacement;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* App-agnostic Tiptap extension providing a Notion-style left-margin drag grip
|
|
71
|
+
* (the `::` handle), block selection, and drag-to-reorder over top-level block
|
|
72
|
+
* nodes.
|
|
73
|
+
*
|
|
74
|
+
* Behavior:
|
|
75
|
+
* - On hover over any top-level block, a `.drag-handle` grip appears in the left
|
|
76
|
+
* margin (forgiving hit zone extends {@link HOVER_SIDE_OUTSET_REM}rem to the
|
|
77
|
+
* sides and into the gap above/between blocks).
|
|
78
|
+
* - Single-clicking the grip selects the block and opens a block action menu.
|
|
79
|
+
* Dragging past a small threshold starts a reorder, showing a floating clone
|
|
80
|
+
* preview (`.notion-drag-preview`) and a `.notion-drop-indicator` line.
|
|
81
|
+
* `Escape` cancels.
|
|
82
|
+
* - While dragging, the source block carries `.notion-block--dragging` and the
|
|
83
|
+
* document element carries `.notion-editor-is-dragging` so apps can style the
|
|
84
|
+
* in-flight state. Apps own all of these CSS class names.
|
|
85
|
+
* - Works for ANY top-level node ProseMirror renders as a direct child of the
|
|
86
|
+
* editor — including `group: "block"`, `draggable: true` atoms such as the
|
|
87
|
+
* plan editor's `planBlock`.
|
|
88
|
+
*
|
|
89
|
+
* The only app-specific coupling — the editor wrapper element the handle and
|
|
90
|
+
* drop indicator are anchored to — is configurable via
|
|
91
|
+
* {@link DragHandleOptions.wrapperSelector}, defaulting to
|
|
92
|
+
* {@link DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR} (`.visual-editor-wrapper`) so the
|
|
93
|
+
* Content editor keeps working byte-identically. The plan editor passes its own
|
|
94
|
+
* wrapper selector via `DragHandle.configure({ wrapperSelector })`.
|
|
95
|
+
*/
|
|
96
|
+
export declare const DragHandle: Extension<DragHandleOptions, any>;
|
|
97
|
+
//# sourceMappingURL=DragHandle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DragHandle.d.ts","sourceRoot":"","sources":["../../src/editor/DragHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQhE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,2BAA2B,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;OAQG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC9B,IAAI,EAAE,UAAU,CAAC;QACjB,IAAI,EAAE,eAAe,CAAC;QACtB,GAAG,EAAE,MAAM,CAAC;KACb,KAAK,OAAO,CAAC;IACd;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,CACxB,IAAI,EAAE,OAAO,EACb,OAAO,EAAE;QACP,IAAI,EAAE,UAAU,CAAC;QACjB,IAAI,EAAE,eAAe,CAAC;QACtB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,UAAU,CAAC;KACxB,KACE,IAAI,CAAC;IACV;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC;CACzE;AA8DD,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5E,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;CACpC,CAAC;AAuSF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,UAAU,mCA68BrB,CAAC"}
|