@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.
Files changed (144) hide show
  1. package/README.md +17 -6
  2. package/dist/collab-ui/agent-identity.d.ts +9 -0
  3. package/dist/collab-ui/agent-identity.d.ts.map +1 -0
  4. package/dist/collab-ui/agent-identity.js +9 -0
  5. package/dist/collab-ui/agent-identity.js.map +1 -0
  6. package/dist/collab-ui/index.d.ts +2 -0
  7. package/dist/collab-ui/index.d.ts.map +1 -1
  8. package/dist/collab-ui/index.js +2 -0
  9. package/dist/collab-ui/index.js.map +1 -1
  10. package/dist/collab-ui/lead-client.d.ts +3 -0
  11. package/dist/collab-ui/lead-client.d.ts.map +1 -0
  12. package/dist/collab-ui/lead-client.js +29 -0
  13. package/dist/collab-ui/lead-client.js.map +1 -0
  14. package/dist/context-ui/ContextMeter.d.ts +10 -0
  15. package/dist/context-ui/ContextMeter.d.ts.map +1 -0
  16. package/dist/context-ui/ContextMeter.js +20 -0
  17. package/dist/context-ui/ContextMeter.js.map +1 -0
  18. package/dist/context-ui/ContextSegmentRow.d.ts +14 -0
  19. package/dist/context-ui/ContextSegmentRow.d.ts.map +1 -0
  20. package/dist/context-ui/ContextSegmentRow.js +25 -0
  21. package/dist/context-ui/ContextSegmentRow.js.map +1 -0
  22. package/dist/context-ui/ContextTreemap.d.ts +7 -0
  23. package/dist/context-ui/ContextTreemap.d.ts.map +1 -0
  24. package/dist/context-ui/ContextTreemap.js +55 -0
  25. package/dist/context-ui/ContextTreemap.js.map +1 -0
  26. package/dist/context-ui/ContextXRayPanel.d.ts +13 -0
  27. package/dist/context-ui/ContextXRayPanel.d.ts.map +1 -0
  28. package/dist/context-ui/ContextXRayPanel.js +120 -0
  29. package/dist/context-ui/ContextXRayPanel.js.map +1 -0
  30. package/dist/context-ui/format.d.ts +6 -0
  31. package/dist/context-ui/format.d.ts.map +1 -0
  32. package/dist/context-ui/format.js +58 -0
  33. package/dist/context-ui/format.js.map +1 -0
  34. package/dist/context-ui/index.d.ts +7 -0
  35. package/dist/context-ui/index.d.ts.map +1 -0
  36. package/dist/context-ui/index.js +6 -0
  37. package/dist/context-ui/index.js.map +1 -0
  38. package/dist/context-ui/types.d.ts +39 -0
  39. package/dist/context-ui/types.d.ts.map +1 -0
  40. package/dist/context-ui/types.js +2 -0
  41. package/dist/context-ui/types.js.map +1 -0
  42. package/dist/design-tweaks/index.d.ts +2 -0
  43. package/dist/design-tweaks/index.d.ts.map +1 -0
  44. package/dist/design-tweaks/index.js +2 -0
  45. package/dist/design-tweaks/index.js.map +1 -0
  46. package/dist/design-tweaks/visual-style-controls.d.ts +90 -0
  47. package/dist/design-tweaks/visual-style-controls.d.ts.map +1 -0
  48. package/dist/design-tweaks/visual-style-controls.js +499 -0
  49. package/dist/design-tweaks/visual-style-controls.js.map +1 -0
  50. package/dist/editor/BubbleToolbar.d.ts +37 -0
  51. package/dist/editor/BubbleToolbar.d.ts.map +1 -0
  52. package/dist/editor/BubbleToolbar.js +171 -0
  53. package/dist/editor/BubbleToolbar.js.map +1 -0
  54. package/dist/editor/CodeBlockNode.d.ts +49 -0
  55. package/dist/editor/CodeBlockNode.d.ts.map +1 -0
  56. package/dist/editor/CodeBlockNode.js +127 -0
  57. package/dist/editor/CodeBlockNode.js.map +1 -0
  58. package/dist/editor/DragHandle.d.ts +97 -0
  59. package/dist/editor/DragHandle.d.ts.map +1 -0
  60. package/dist/editor/DragHandle.js +1066 -0
  61. package/dist/editor/DragHandle.js.map +1 -0
  62. package/dist/editor/DragHandle.spec.d.ts +2 -0
  63. package/dist/editor/DragHandle.spec.d.ts.map +1 -0
  64. package/dist/editor/DragHandle.spec.js +407 -0
  65. package/dist/editor/DragHandle.spec.js.map +1 -0
  66. package/dist/editor/ImageExtension.d.ts +63 -0
  67. package/dist/editor/ImageExtension.d.ts.map +1 -0
  68. package/dist/editor/ImageExtension.js +243 -0
  69. package/dist/editor/ImageExtension.js.map +1 -0
  70. package/dist/editor/ImageExtension.roundtrip.spec.d.ts +2 -0
  71. package/dist/editor/ImageExtension.roundtrip.spec.d.ts.map +1 -0
  72. package/dist/editor/ImageExtension.roundtrip.spec.js +103 -0
  73. package/dist/editor/ImageExtension.roundtrip.spec.js.map +1 -0
  74. package/dist/editor/RichMarkdownEditor.collab.spec.d.ts +2 -0
  75. package/dist/editor/RichMarkdownEditor.collab.spec.d.ts.map +1 -0
  76. package/dist/editor/RichMarkdownEditor.collab.spec.js +65 -0
  77. package/dist/editor/RichMarkdownEditor.collab.spec.js.map +1 -0
  78. package/dist/editor/RichMarkdownEditor.d.ts +52 -0
  79. package/dist/editor/RichMarkdownEditor.d.ts.map +1 -0
  80. package/dist/editor/RichMarkdownEditor.js +38 -0
  81. package/dist/editor/RichMarkdownEditor.js.map +1 -0
  82. package/dist/editor/RichMarkdownEditor.roundtrip.spec.d.ts +2 -0
  83. package/dist/editor/RichMarkdownEditor.roundtrip.spec.d.ts.map +1 -0
  84. package/dist/editor/RichMarkdownEditor.roundtrip.spec.js +186 -0
  85. package/dist/editor/RichMarkdownEditor.roundtrip.spec.js.map +1 -0
  86. package/dist/editor/RunId.d.ts +28 -0
  87. package/dist/editor/RunId.d.ts.map +1 -0
  88. package/dist/editor/RunId.js +60 -0
  89. package/dist/editor/RunId.js.map +1 -0
  90. package/dist/editor/SharedRichEditor.d.ts +110 -0
  91. package/dist/editor/SharedRichEditor.d.ts.map +1 -0
  92. package/dist/editor/SharedRichEditor.js +144 -0
  93. package/dist/editor/SharedRichEditor.js.map +1 -0
  94. package/dist/editor/SlashCommandMenu.d.ts +41 -0
  95. package/dist/editor/SlashCommandMenu.d.ts.map +1 -0
  96. package/dist/editor/SlashCommandMenu.js +221 -0
  97. package/dist/editor/SlashCommandMenu.js.map +1 -0
  98. package/dist/editor/disableHistory.spec.d.ts +2 -0
  99. package/dist/editor/disableHistory.spec.d.ts.map +1 -0
  100. package/dist/editor/disableHistory.spec.js +73 -0
  101. package/dist/editor/disableHistory.spec.js.map +1 -0
  102. package/dist/editor/extensions.d.ts +178 -0
  103. package/dist/editor/extensions.d.ts.map +1 -0
  104. package/dist/editor/extensions.js +224 -0
  105. package/dist/editor/extensions.js.map +1 -0
  106. package/dist/editor/gfmDoc.d.ts +24 -0
  107. package/dist/editor/gfmDoc.d.ts.map +1 -0
  108. package/dist/editor/gfmDoc.js +83 -0
  109. package/dist/editor/gfmDoc.js.map +1 -0
  110. package/dist/editor/gfmDoc.spec.d.ts +2 -0
  111. package/dist/editor/gfmDoc.spec.d.ts.map +1 -0
  112. package/dist/editor/gfmDoc.spec.js +194 -0
  113. package/dist/editor/gfmDoc.spec.js.map +1 -0
  114. package/dist/editor/index.d.ts +14 -0
  115. package/dist/editor/index.d.ts.map +1 -0
  116. package/dist/editor/index.js +13 -0
  117. package/dist/editor/index.js.map +1 -0
  118. package/dist/editor/structuralReorderUndo.spec.d.ts +2 -0
  119. package/dist/editor/structuralReorderUndo.spec.d.ts.map +1 -0
  120. package/dist/editor/structuralReorderUndo.spec.js +120 -0
  121. package/dist/editor/structuralReorderUndo.spec.js.map +1 -0
  122. package/dist/editor/surgical-apply.d.ts +66 -0
  123. package/dist/editor/surgical-apply.d.ts.map +1 -0
  124. package/dist/editor/surgical-apply.js +147 -0
  125. package/dist/editor/surgical-apply.js.map +1 -0
  126. package/dist/editor/surgical-apply.spec.d.ts +2 -0
  127. package/dist/editor/surgical-apply.spec.d.ts.map +1 -0
  128. package/dist/editor/surgical-apply.spec.js +257 -0
  129. package/dist/editor/surgical-apply.spec.js.map +1 -0
  130. package/dist/editor/useCollabReconcile.concurrent.spec.d.ts +2 -0
  131. package/dist/editor/useCollabReconcile.concurrent.spec.d.ts.map +1 -0
  132. package/dist/editor/useCollabReconcile.concurrent.spec.js +329 -0
  133. package/dist/editor/useCollabReconcile.concurrent.spec.js.map +1 -0
  134. package/dist/editor/useCollabReconcile.d.ts +110 -0
  135. package/dist/editor/useCollabReconcile.d.ts.map +1 -0
  136. package/dist/editor/useCollabReconcile.idempotent.spec.d.ts +2 -0
  137. package/dist/editor/useCollabReconcile.idempotent.spec.d.ts.map +1 -0
  138. package/dist/editor/useCollabReconcile.idempotent.spec.js +248 -0
  139. package/dist/editor/useCollabReconcile.idempotent.spec.js.map +1 -0
  140. package/dist/editor/useCollabReconcile.js +440 -0
  141. package/dist/editor/useCollabReconcile.js.map +1 -0
  142. package/dist/editor.css +510 -0
  143. package/migration-manifest.json +4 -0
  144. 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"}