@reforma/components 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/RichInput/RichInput.d.ts +1 -1
- package/dist/RichInput/RichInput.d.ts.map +1 -1
- package/dist/RichInput/RichInput.js +126 -123
- package/dist/RichInput/RichInput.js.map +1 -1
- package/dist/chat/ComposerBanner/ComposerBanner.d.ts +6 -1
- package/dist/chat/ComposerBanner/ComposerBanner.d.ts.map +1 -1
- package/dist/chat/ComposerBanner/ComposerBanner.js +60 -40
- package/dist/chat/ComposerBanner/ComposerBanner.js.map +1 -1
- package/dist/chat/ComposerBanner/ComposerBanner.module.css +1 -1
- package/dist/chat/ComposerBanner/ComposerBanner.module.css.js +13 -9
- package/dist/chat/ComposerBanner/ComposerBanner.module.css.js.map +1 -1
- package/dist/chat/Conversation/ConversationPendingLoader.d.ts.map +1 -1
- package/dist/chat/Conversation/ConversationPendingLoader.js +1 -1
- package/dist/chat/Conversation/ConversationPendingLoader.js.map +1 -1
- package/dist/chat/Message/normalize/normalizeMessageParts.d.ts +1 -1
- package/dist/chat/Message/normalize/normalizeMessageParts.d.ts.map +1 -1
- package/dist/chat/Message/normalize/normalizeMessageParts.js +1 -1
- package/dist/chat/Message/normalize/normalizeMessageParts.js.map +1 -1
- package/dist/chat/Message/parts/MessagePart.d.ts.map +1 -1
- package/dist/chat/Message/parts/MessagePart.js +1 -1
- package/dist/chat/Message/parts/MessagePart.js.map +1 -1
- package/dist/chat/Message/parts/backgroundResultPart.js +1 -1
- package/dist/chat/Message/parts/backgroundResultPart.js.map +1 -1
- package/dist/chat/Message/parts/collectMessageSources.d.ts +1 -1
- package/dist/chat/Message/parts/collectMessageSources.d.ts.map +1 -1
- package/dist/chat/Message/parts/collectMessageSources.js +1 -1
- package/dist/chat/Message/parts/collectMessageSources.js.map +1 -1
- package/dist/chat/Message/parts/contextCompactionPart.js +1 -1
- package/dist/chat/Message/parts/contextCompactionPart.js.map +1 -1
- package/dist/chat/Message/segments/analyzeGroupedSegment.js +5 -5
- package/dist/chat/Message/segments/analyzeGroupedSegment.js.map +1 -1
- package/dist/chat/Message/segments/recentStreamingPhaseToolGroups.js +1 -1
- package/dist/chat/Message/segments/recentStreamingPhaseToolGroups.js.map +1 -1
- package/dist/chat/Message/turn/workedCollapse.js +1 -1
- package/dist/chat/Message/turn/workedCollapse.js.map +1 -1
- package/dist/chat/Tool/Tool.js +1 -1
- package/dist/chat/Tool/Tool.js.map +1 -1
- package/dist/chat/Tool/agent/AgentTool.d.ts.map +1 -1
- package/dist/chat/Tool/agent/AgentTool.js +73 -73
- package/dist/chat/Tool/agent/AgentTool.js.map +1 -1
- package/dist/chat/Tool/bash/BashTool.d.ts.map +1 -1
- package/dist/chat/Tool/bash/BashTool.js +1 -1
- package/dist/chat/Tool/bash/BashTool.js.map +1 -1
- package/dist/chat/Tool/create-directory/CreateDirectoryTool.js +1 -1
- package/dist/chat/Tool/create-directory/CreateDirectoryTool.js.map +1 -1
- package/dist/chat/Tool/default/Default.d.ts.map +1 -1
- package/dist/chat/Tool/default/Default.js +1 -1
- package/dist/chat/Tool/default/Default.js.map +1 -1
- package/dist/chat/Tool/dev-server/DevServerRestartTool.js +1 -1
- package/dist/chat/Tool/dev-server/DevServerRestartTool.js.map +1 -1
- package/dist/chat/Tool/dev-server/DevServerStatusTool.js +1 -1
- package/dist/chat/Tool/dev-server/DevServerStatusTool.js.map +1 -1
- package/dist/chat/Tool/edit/EditTool.js +1 -1
- package/dist/chat/Tool/edit/EditTool.js.map +1 -1
- package/dist/chat/Tool/fetch/FetchTool.js +1 -1
- package/dist/chat/Tool/fetch/FetchTool.js.map +1 -1
- package/dist/chat/Tool/fileChangesFromToolParts.js +1 -1
- package/dist/chat/Tool/fileChangesFromToolParts.js.map +1 -1
- package/dist/chat/Tool/get-background-result/GetBackgroundResultTool.js +1 -1
- package/dist/chat/Tool/get-background-result/GetBackgroundResultTool.js.map +1 -1
- package/dist/chat/Tool/get-errors/GetErrorsTool.js +1 -1
- package/dist/chat/Tool/get-errors/GetErrorsTool.js.map +1 -1
- package/dist/chat/Tool/glob/GlobTool.js +1 -1
- package/dist/chat/Tool/glob/GlobTool.js.map +1 -1
- package/dist/chat/Tool/grep/GrepTool.js +1 -1
- package/dist/chat/Tool/grep/GrepTool.js.map +1 -1
- package/dist/chat/Tool/helpers.d.ts +1 -1
- package/dist/chat/Tool/helpers.d.ts.map +1 -1
- package/dist/chat/Tool/helpers.js +1 -1
- package/dist/chat/Tool/helpers.js.map +1 -1
- package/dist/chat/Tool/image-asset/ImageAssetTool.js +1 -1
- package/dist/chat/Tool/image-asset/ImageAssetTool.js.map +1 -1
- package/dist/chat/Tool/install-dependencies/InstallDependenciesTool.js +1 -1
- package/dist/chat/Tool/install-dependencies/InstallDependenciesTool.js.map +1 -1
- package/dist/chat/Tool/install-plugin/InstallPlugin.js +1 -1
- package/dist/chat/Tool/install-plugin/InstallPlugin.js.map +1 -1
- package/dist/chat/Tool/integration-card/IntegrationActionCard.d.ts +3 -1
- package/dist/chat/Tool/integration-card/IntegrationActionCard.d.ts.map +1 -1
- package/dist/chat/Tool/integration-card/IntegrationActionCard.js +88 -82
- package/dist/chat/Tool/integration-card/IntegrationActionCard.js.map +1 -1
- package/dist/chat/Tool/list-directory/normalizeListDirectoryTools.js +1 -1
- package/dist/chat/Tool/list-directory/normalizeListDirectoryTools.js.map +1 -1
- package/dist/chat/Tool/mcp-tools/CallDynamicTool.js +1 -1
- package/dist/chat/Tool/mcp-tools/CallDynamicTool.js.map +1 -1
- package/dist/chat/Tool/mcp-tools/GetDynamicToolsTool.js +1 -1
- package/dist/chat/Tool/mcp-tools/GetDynamicToolsTool.js.map +1 -1
- package/dist/chat/Tool/mcp-tools/GetMcpResourcesTool.js +1 -1
- package/dist/chat/Tool/mcp-tools/GetMcpResourcesTool.js.map +1 -1
- package/dist/chat/Tool/mcp-tools/McpAuth.js +1 -1
- package/dist/chat/Tool/mcp-tools/McpAuth.js.map +1 -1
- package/dist/chat/Tool/memory/MemoryTool.js +1 -1
- package/dist/chat/Tool/memory/MemoryTool.js.map +1 -1
- package/dist/chat/Tool/move-file/MoveFileTool.js +1 -1
- package/dist/chat/Tool/move-file/MoveFileTool.js.map +1 -1
- package/dist/chat/Tool/plan/CreatePlanTool.js +1 -1
- package/dist/chat/Tool/plan/CreatePlanTool.js.map +1 -1
- package/dist/chat/Tool/preamble/PreambleTool.js +1 -1
- package/dist/chat/Tool/preamble/PreambleTool.js.map +1 -1
- package/dist/chat/Tool/project-build/BuildTool.js +1 -1
- package/dist/chat/Tool/project-build/BuildTool.js.map +1 -1
- package/dist/chat/Tool/project-env/ProjectEnvTool.js +1 -1
- package/dist/chat/Tool/project-env/ProjectEnvTool.js.map +1 -1
- package/dist/chat/Tool/read/normalizeReadTools.js +1 -1
- package/dist/chat/Tool/read/normalizeReadTools.js.map +1 -1
- package/dist/chat/Tool/read-lints/ReadLintsTool.js +1 -1
- package/dist/chat/Tool/read-lints/ReadLintsTool.js.map +1 -1
- package/dist/chat/Tool/remove-file/RemoveFileTool.js +1 -1
- package/dist/chat/Tool/remove-file/RemoveFileTool.js.map +1 -1
- package/dist/chat/Tool/scaffold-project/ScaffoldProjectTool.js +1 -1
- package/dist/chat/Tool/scaffold-project/ScaffoldProjectTool.js.map +1 -1
- package/dist/chat/Tool/screenshot/CaptureScreenshotTool.js +3 -3
- package/dist/chat/Tool/screenshot/CaptureScreenshotTool.js.map +1 -1
- package/dist/chat/Tool/skill/SkillTool.js +1 -1
- package/dist/chat/Tool/skill/SkillTool.js.map +1 -1
- package/dist/chat/Tool/waiting/WaitingTool.js +1 -1
- package/dist/chat/Tool/waiting/WaitingTool.js.map +1 -1
- package/dist/chat/Tool/web-search/WebSearchTool.js +1 -1
- package/dist/chat/Tool/web-search/WebSearchTool.js.map +1 -1
- package/package.json +4 -4
|
@@ -40,7 +40,7 @@ export type RichInputProps = {
|
|
|
40
40
|
ref?: Ref<RichInputHandle>;
|
|
41
41
|
};
|
|
42
42
|
/**
|
|
43
|
-
* An editor recreate (
|
|
43
|
+
* An editor recreate (triggers or markdown change) must not pull focus
|
|
44
44
|
* out of a comment, code editor, or other field. First mount has no root yet and still autofocuses.
|
|
45
45
|
*/
|
|
46
46
|
export declare function shouldYieldRichInputAutofocus(ownRoot: Element | null): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichInput.d.ts","sourceRoot":"","sources":["../../src/RichInput/RichInput.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAOH,KAAK,SAAS,EACd,KAAK,GAAG,EACX,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EACR,WAAW,EAEX,eAAe,EACf,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,EAGnB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG;IACzB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACvC;;;;OAIG;IACH,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kHAAkH;IAClH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"RichInput.d.ts","sourceRoot":"","sources":["../../src/RichInput/RichInput.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAOH,KAAK,SAAS,EACd,KAAK,GAAG,EACX,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EACR,WAAW,EAEX,eAAe,EACf,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,EAGnB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG;IACzB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACvC;;;;OAIG;IACH,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kHAAkH;IAClH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC;CAC9B,CAAC;AA6PF;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAgB9E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,QAAyB,EACzB,aAAa,EACb,gBAAgB,EAChB,WAAgB,EAChB,SAAS,EACT,QAAQ,EACR,QAAe,EACf,SAAS,EACT,SAAc,EACd,SAAS,EACT,aAAqB,EACrB,YAAY,EAAE,SAAS,EACvB,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,EAAE,EACF,GAAG,GACN,EAAE,cAAc,GAAG,SAAS,CA8S5B"}
|
|
@@ -1,31 +1,32 @@
|
|
|
1
|
-
import { clamp as C, cn as
|
|
2
|
-
import { mergeAttributes as
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { ListKit as
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import { PluginKey as
|
|
14
|
-
import { useEditor as
|
|
15
|
-
import { useState as T, useRef as
|
|
16
|
-
import { pastedTextToMentionContent as
|
|
1
|
+
import { clamp as C, cn as G } from "@reforma/lib";
|
|
2
|
+
import { mergeAttributes as W } from "@tiptap/core";
|
|
3
|
+
import X from "@tiptap/extension-bold";
|
|
4
|
+
import Q from "@tiptap/extension-code";
|
|
5
|
+
import V from "@tiptap/extension-document";
|
|
6
|
+
import Z from "@tiptap/extension-hard-break";
|
|
7
|
+
import ee from "@tiptap/extension-history";
|
|
8
|
+
import te from "@tiptap/extension-italic";
|
|
9
|
+
import { ListKit as ne, OrderedList as oe } from "@tiptap/extension-list";
|
|
10
|
+
import re from "@tiptap/extension-paragraph";
|
|
11
|
+
import ie from "@tiptap/extension-placeholder";
|
|
12
|
+
import se from "@tiptap/extension-text";
|
|
13
|
+
import { PluginKey as ce } from "@tiptap/pm/state";
|
|
14
|
+
import { useEditor as ue, EditorContent as ae } from "@tiptap/react";
|
|
15
|
+
import { useState as T, useRef as le, useLayoutEffect as K, useEffect as P, useImperativeHandle as me, createElement as de } from "react";
|
|
16
|
+
import { pastedTextToMentionContent as fe, emptyComposerDoc as E, mentionNodes as k, docsEqual as pe, docToPlainText as he } from "./composerDoc.js";
|
|
17
17
|
import { handleComposerKeyDown as ye } from "./composerKeymap.js";
|
|
18
18
|
import { ComposerMention as ge } from "./composerMention.js";
|
|
19
19
|
import { defaultSerializeMention as Me, mentionAttrsFromNode as xe, RichInputMentionContext as Ee, defaultRenderMention as be } from "./mentionRender.js";
|
|
20
|
-
import
|
|
20
|
+
import w from "./RichInput.module.css.js";
|
|
21
21
|
import { RichInputTriggerMenu as Te } from "./RichInputTriggerMenu.js";
|
|
22
|
-
import { jsxs as
|
|
23
|
-
const
|
|
24
|
-
function
|
|
22
|
+
import { jsxs as De, jsx as O } from "react/jsx-runtime";
|
|
23
|
+
const B = [];
|
|
24
|
+
function Se(t) {
|
|
25
25
|
let i = null;
|
|
26
26
|
return {
|
|
27
|
-
triggers:
|
|
27
|
+
triggers: B,
|
|
28
28
|
submitOnEnter: !1,
|
|
29
|
+
placeholder: "",
|
|
29
30
|
getMenu: () => i,
|
|
30
31
|
setMenu: (u) => {
|
|
31
32
|
i = u, t(u);
|
|
@@ -43,7 +44,7 @@ function De(t) {
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
|
-
function
|
|
47
|
+
function L(t, i, d) {
|
|
47
48
|
const u = t.getAnchorRect?.();
|
|
48
49
|
return u ? {
|
|
49
50
|
x: u.left,
|
|
@@ -54,7 +55,7 @@ function w(t, i, f) {
|
|
|
54
55
|
x: i.left,
|
|
55
56
|
top: i.top,
|
|
56
57
|
bottom: i.bottom
|
|
57
|
-
} :
|
|
58
|
+
} : d ?? {
|
|
58
59
|
x: 0,
|
|
59
60
|
top: 0,
|
|
60
61
|
bottom: 0
|
|
@@ -62,65 +63,65 @@ function w(t, i, f) {
|
|
|
62
63
|
}
|
|
63
64
|
function Ce(t, i) {
|
|
64
65
|
return () => {
|
|
65
|
-
let
|
|
66
|
-
const p = (s,
|
|
66
|
+
let d = i, u = 0;
|
|
67
|
+
const p = (s, o) => {
|
|
67
68
|
const a = ++u;
|
|
68
|
-
Promise.resolve(s.onSearch(
|
|
69
|
+
Promise.resolve(s.onSearch(o)).then((c) => {
|
|
69
70
|
a === u && t.setMenuItems(c);
|
|
70
71
|
});
|
|
71
72
|
};
|
|
72
73
|
return {
|
|
73
74
|
onStart: (s) => {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
char:
|
|
77
|
-
accessibilityLabel:
|
|
75
|
+
const o = t.triggers.find((c) => c.char === d), a = s.clientRect?.();
|
|
76
|
+
o && (d = o.char, t.setMenu({
|
|
77
|
+
char: o.char,
|
|
78
|
+
accessibilityLabel: o.accessibilityLabel,
|
|
78
79
|
items: [],
|
|
79
80
|
selectedKey: null,
|
|
80
|
-
placement:
|
|
81
|
-
anchor:
|
|
81
|
+
placement: o.placement ?? "auto",
|
|
82
|
+
anchor: L(o, a),
|
|
82
83
|
command: (c) => s.command(c)
|
|
83
|
-
}), p(
|
|
84
|
+
}), p(o, s.query));
|
|
84
85
|
},
|
|
85
86
|
onUpdate: (s) => {
|
|
86
|
-
const
|
|
87
|
-
!
|
|
87
|
+
const o = t.triggers.find((y) => y.char === d), a = s.clientRect?.(), c = t.getMenu();
|
|
88
|
+
!o || !c || (t.setMenu({
|
|
88
89
|
...c,
|
|
89
|
-
placement:
|
|
90
|
-
anchor:
|
|
90
|
+
placement: o.placement ?? c.placement,
|
|
91
|
+
anchor: L(o, a, c.anchor),
|
|
91
92
|
command: (y) => s.command(y)
|
|
92
|
-
}), p(
|
|
93
|
+
}), p(o, s.query));
|
|
93
94
|
},
|
|
94
95
|
onExit: () => {
|
|
95
|
-
u += 1, t.triggers.find((s) => s.char ===
|
|
96
|
+
u += 1, t.triggers.find((s) => s.char === d)?.onClose?.(), t.setMenu(null);
|
|
96
97
|
},
|
|
97
98
|
onKeyDown: ({
|
|
98
99
|
event: s
|
|
99
100
|
}) => {
|
|
100
|
-
const
|
|
101
|
-
if (!
|
|
101
|
+
const o = t.getMenu();
|
|
102
|
+
if (!o)
|
|
102
103
|
return !1;
|
|
103
104
|
if (s.key === "Escape")
|
|
104
|
-
return
|
|
105
|
-
if ((s.key === "ArrowDown" || s.key === "ArrowUp") &&
|
|
106
|
-
const a =
|
|
105
|
+
return o.items.length === 0 ? !1 : (t.setMenu(null), !0);
|
|
106
|
+
if ((s.key === "ArrowDown" || s.key === "ArrowUp") && o.items.length > 0) {
|
|
107
|
+
const a = o.items.findIndex((y) => y.value === o.selectedKey), c = s.key === "ArrowDown" ? o.items[Math.min(a + 1, o.items.length - 1)] : o.items[Math.max(a - 1, 0)];
|
|
107
108
|
return t.setMenu({
|
|
108
|
-
...
|
|
109
|
+
...o,
|
|
109
110
|
selectedKey: c?.value ?? null
|
|
110
111
|
}), !0;
|
|
111
112
|
}
|
|
112
|
-
if ((s.key === "Enter" || s.key === "Tab" || s.key === " ") &&
|
|
113
|
-
const a =
|
|
113
|
+
if ((s.key === "Enter" || s.key === "Tab" || s.key === " ") && o.items.length > 0) {
|
|
114
|
+
const a = o.items.find((c) => c.value === o.selectedKey) ?? o.items[0];
|
|
114
115
|
return !a || s.key === " " && a.kind !== "link" ? !1 : a.action ? (a.action({
|
|
115
116
|
setItems: (c) => t.setMenuItems(c)
|
|
116
|
-
}), !0) : (
|
|
117
|
+
}), !0) : (o.command(a), !0);
|
|
117
118
|
}
|
|
118
119
|
return !1;
|
|
119
120
|
}
|
|
120
121
|
};
|
|
121
122
|
};
|
|
122
123
|
}
|
|
123
|
-
const
|
|
124
|
+
const A = ["textarea", 'input:not([type="hidden"])', '[contenteditable]:not([contenteditable="false"])', ".cm-editor", ".monaco-editor"].join(", ");
|
|
124
125
|
function Ie(t) {
|
|
125
126
|
if (!t || t.isDestroyed)
|
|
126
127
|
return null;
|
|
@@ -131,13 +132,13 @@ function Ie(t) {
|
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
function Re(t) {
|
|
134
|
-
if (t.closest(
|
|
135
|
+
if (t.closest(A))
|
|
135
136
|
return !0;
|
|
136
137
|
if (!(t instanceof HTMLIFrameElement))
|
|
137
138
|
return !1;
|
|
138
139
|
try {
|
|
139
140
|
const i = t.contentDocument?.activeElement;
|
|
140
|
-
return !!(i && i !== t.contentDocument?.body && i !== t.contentDocument?.documentElement && i.closest(
|
|
141
|
+
return !!(i && i !== t.contentDocument?.body && i !== t.contentDocument?.documentElement && i.closest(A));
|
|
141
142
|
} catch {
|
|
142
143
|
return !1;
|
|
143
144
|
}
|
|
@@ -151,84 +152,84 @@ function Ke(t) {
|
|
|
151
152
|
function Qe({
|
|
152
153
|
value: t,
|
|
153
154
|
onChange: i,
|
|
154
|
-
triggers:
|
|
155
|
+
triggers: d = B,
|
|
155
156
|
renderMention: u,
|
|
156
157
|
serializeMention: p,
|
|
157
158
|
placeholder: s = "",
|
|
158
|
-
className:
|
|
159
|
+
className: o,
|
|
159
160
|
disabled: a,
|
|
160
161
|
markdown: c = !0,
|
|
161
162
|
autoFocus: y,
|
|
162
|
-
minHeight:
|
|
163
|
-
maxHeight:
|
|
164
|
-
submitOnEnter:
|
|
163
|
+
minHeight: N = 24,
|
|
164
|
+
maxHeight: D,
|
|
165
|
+
submitOnEnter: v = !1,
|
|
165
166
|
"aria-label": I,
|
|
166
167
|
onSubmit: z,
|
|
167
168
|
onEscape: F,
|
|
168
|
-
onPasteFiles:
|
|
169
|
-
onPasteText:
|
|
169
|
+
onPasteFiles: $,
|
|
170
|
+
onPasteText: j,
|
|
170
171
|
id: R,
|
|
171
|
-
ref:
|
|
172
|
+
ref: q
|
|
172
173
|
}) {
|
|
173
|
-
const [h,
|
|
174
|
-
const e =
|
|
174
|
+
const [h, H] = T(null), [b] = T(() => {
|
|
175
|
+
const e = Se(H);
|
|
175
176
|
return () => e;
|
|
176
|
-
}),
|
|
177
|
-
const
|
|
178
|
-
return /* @__PURE__ */
|
|
179
|
-
}), M =
|
|
177
|
+
}), r = b(), [J] = T(() => (l) => {
|
|
178
|
+
const f = b().renderMention ?? be;
|
|
179
|
+
return /* @__PURE__ */ de(f, l);
|
|
180
|
+
}), M = le(1), x = (e) => {
|
|
180
181
|
M.current = e.state.selection.head;
|
|
181
182
|
};
|
|
182
|
-
|
|
183
|
-
const
|
|
183
|
+
r.triggers = d, r.submitOnEnter = v, r.placeholder = s, r.onChange = i, r.onPasteFiles = $, r.onPasteText = j, r.renderMention = u, r.serializeMention = p, r.onSubmit = z, r.onEscape = F;
|
|
184
|
+
const U = d.map((e) => `${e.char}:${e.position ?? "any"}`).join("|"), [Y, _] = T(null), n = ue({
|
|
184
185
|
immediatelyRender: !1,
|
|
185
186
|
editable: !a,
|
|
186
|
-
autofocus: y && !Ke(
|
|
187
|
-
extensions: [
|
|
187
|
+
autofocus: y && !Ke(Y) ? "end" : !1,
|
|
188
|
+
extensions: [V, re, se, Z.extend({
|
|
188
189
|
addKeyboardShortcuts() {
|
|
189
190
|
return {};
|
|
190
191
|
}
|
|
191
|
-
}),
|
|
192
|
+
}), ee, ...c ? [X, te, Q, ne.configure({
|
|
192
193
|
orderedList: !1,
|
|
193
194
|
taskItem: !1,
|
|
194
195
|
taskList: !1
|
|
195
|
-
}),
|
|
196
|
+
}), oe.extend({
|
|
196
197
|
// CSS draws the numbers (see `.editor ol`); seed the counter from `start`.
|
|
197
198
|
renderHTML({
|
|
198
199
|
node: e,
|
|
199
200
|
HTMLAttributes: l
|
|
200
201
|
}) {
|
|
201
|
-
return ["ol",
|
|
202
|
+
return ["ol", W(this.options.HTMLAttributes, l, {
|
|
202
203
|
style: `counter-reset: rich-input-ol ${e.attrs.start - 1}`
|
|
203
204
|
}), 0];
|
|
204
205
|
}
|
|
205
|
-
})] : [],
|
|
206
|
-
placeholder:
|
|
206
|
+
})] : [], ie.configure({
|
|
207
|
+
placeholder: () => r.placeholder
|
|
207
208
|
}), ge.configure({
|
|
208
209
|
// Backspace on a chip must not leave a stray `@` / `/` trigger char.
|
|
209
210
|
deleteTriggerWithBackspace: !0,
|
|
210
211
|
renderText: ({
|
|
211
212
|
node: e
|
|
212
|
-
}) => (
|
|
213
|
-
suggestions:
|
|
213
|
+
}) => (r.serializeMention ?? Me)(xe(e.attrs)),
|
|
214
|
+
suggestions: d.map((e) => ({
|
|
214
215
|
char: e.char,
|
|
215
|
-
pluginKey: new
|
|
216
|
+
pluginKey: new ce(`rich-input-${e.char}`),
|
|
216
217
|
startOfLine: e.position === "start",
|
|
217
218
|
allowedPrefixes: e.position === "start" ? null : void 0,
|
|
218
219
|
items: () => [],
|
|
219
|
-
render: Ce(
|
|
220
|
+
render: Ce(r, e.char),
|
|
220
221
|
command: ({
|
|
221
222
|
editor: l,
|
|
222
|
-
range:
|
|
223
|
+
range: f,
|
|
223
224
|
props: g
|
|
224
225
|
}) => {
|
|
225
226
|
const m = g;
|
|
226
227
|
if (!m.action) {
|
|
227
228
|
if (m.run) {
|
|
228
|
-
l.chain().focus().deleteRange(
|
|
229
|
+
l.chain().focus().deleteRange(f).run(), m.run();
|
|
229
230
|
return;
|
|
230
231
|
}
|
|
231
|
-
m.kind && l.chain().focus().insertContentAt(
|
|
232
|
+
m.kind && l.chain().focus().insertContentAt(f, k({
|
|
232
233
|
id: m.value,
|
|
233
234
|
label: m.displayText ?? m.label,
|
|
234
235
|
kind: m.kind,
|
|
@@ -248,33 +249,33 @@ function Qe({
|
|
|
248
249
|
...I ? {
|
|
249
250
|
"aria-label": I
|
|
250
251
|
} : {},
|
|
251
|
-
class:
|
|
252
|
-
style: [`min-height:${
|
|
252
|
+
class: w.editor,
|
|
253
|
+
style: [`min-height:${N}px`, D != null ? `max-height:${D}px` : null, D != null ? "overflow-y:auto" : null].filter(Boolean).join(";")
|
|
253
254
|
},
|
|
254
255
|
handleKeyDown: (e, l) => ye(e, l, {
|
|
255
|
-
submitOnEnter:
|
|
256
|
-
hasMenuItems: !!
|
|
257
|
-
onSubmit: (
|
|
258
|
-
onEscape:
|
|
259
|
-
closeMenu: () =>
|
|
256
|
+
submitOnEnter: r.submitOnEnter,
|
|
257
|
+
hasMenuItems: !!r.getMenu()?.items.length,
|
|
258
|
+
onSubmit: (f) => r.onSubmit?.(r.getEditorDoc(), f),
|
|
259
|
+
onEscape: r.onEscape,
|
|
260
|
+
closeMenu: () => r.setMenu(null)
|
|
260
261
|
}),
|
|
261
262
|
handlePaste: (e, l) => {
|
|
262
|
-
const
|
|
263
|
-
if (
|
|
264
|
-
return
|
|
263
|
+
const f = l.clipboardData?.files;
|
|
264
|
+
if (f && f.length > 0 && r.onPasteFiles)
|
|
265
|
+
return r.onPasteFiles([...f]), l.preventDefault(), !0;
|
|
265
266
|
const g = l.clipboardData?.getData("text/plain") ?? "";
|
|
266
|
-
if (g &&
|
|
267
|
+
if (g && r.onPasteText?.(g))
|
|
267
268
|
return l.preventDefault(), !0;
|
|
268
|
-
const m =
|
|
269
|
-
return !m || !g || !/@https?:\/\/\S/i.test(g) ? !1 : (l.preventDefault(),
|
|
270
|
-
|
|
269
|
+
const m = r.triggers.find((S) => S.char === "@");
|
|
270
|
+
return !m || !g || !/@https?:\/\/\S/i.test(g) ? !1 : (l.preventDefault(), fe(g, m).then((S) => {
|
|
271
|
+
r.setMenu(null), r.insertContent(S);
|
|
271
272
|
}), !0);
|
|
272
273
|
}
|
|
273
274
|
},
|
|
274
275
|
onUpdate: ({
|
|
275
276
|
editor: e
|
|
276
277
|
}) => {
|
|
277
|
-
x(e),
|
|
278
|
+
x(e), r.onChange?.(e.getJSON());
|
|
278
279
|
},
|
|
279
280
|
onSelectionUpdate: ({
|
|
280
281
|
editor: e
|
|
@@ -286,44 +287,46 @@ function Qe({
|
|
|
286
287
|
}) => {
|
|
287
288
|
x(e);
|
|
288
289
|
}
|
|
289
|
-
}, [
|
|
290
|
+
}, [U, c]);
|
|
290
291
|
return K(() => {
|
|
291
|
-
|
|
292
|
-
}, [
|
|
293
|
-
|
|
292
|
+
_(Ie(n));
|
|
293
|
+
}, [n]), r.getEditorDoc = () => n?.getJSON() ?? E(), r.insertContent = (e) => {
|
|
294
|
+
n?.chain().focus().insertContent(e).run();
|
|
294
295
|
}, K(() => {
|
|
295
|
-
if (!(!
|
|
296
|
-
|
|
296
|
+
if (!(!n || t == null) && !pe(n.getJSON(), t)) {
|
|
297
|
+
n.chain().setMeta("addToHistory", !1).setContent(t, {
|
|
297
298
|
emitUpdate: !1
|
|
298
299
|
}).run();
|
|
299
|
-
const e = C(1, M.current,
|
|
300
|
-
M.current = e,
|
|
300
|
+
const e = C(1, M.current, n.state.doc.content.size);
|
|
301
|
+
M.current = e, n.isFocused && n.commands.setTextSelection(e);
|
|
301
302
|
}
|
|
302
|
-
}, [
|
|
303
|
-
|
|
304
|
-
}, [
|
|
303
|
+
}, [n, t]), P(() => {
|
|
304
|
+
n?.setEditable(!a);
|
|
305
|
+
}, [n, a]), P(() => {
|
|
306
|
+
n && !n.isDestroyed && n.view.dispatch(n.state.tr);
|
|
307
|
+
}, [n, s]), me(q, () => ({
|
|
305
308
|
focus: () => {
|
|
306
|
-
if (!
|
|
309
|
+
if (!n)
|
|
307
310
|
return;
|
|
308
|
-
const e = C(1, M.current,
|
|
309
|
-
|
|
311
|
+
const e = C(1, M.current, n.state.doc.content.size);
|
|
312
|
+
n.chain().focus().setTextSelection(e).run();
|
|
310
313
|
},
|
|
311
|
-
getDoc: () =>
|
|
312
|
-
getPlainText: () => he(
|
|
314
|
+
getDoc: () => n?.getJSON() ?? E(),
|
|
315
|
+
getPlainText: () => he(n?.getJSON() ?? E(), b().serializeMention),
|
|
313
316
|
insertMention: (e) => {
|
|
314
|
-
if (!
|
|
317
|
+
if (!n)
|
|
315
318
|
return;
|
|
316
|
-
const l = C(1, M.current,
|
|
317
|
-
|
|
319
|
+
const l = C(1, M.current, n.state.doc.content.size);
|
|
320
|
+
n.chain().insertContentAt(l, k(e)).focus().run(), x(n);
|
|
318
321
|
},
|
|
319
322
|
appendText: (e) => {
|
|
320
|
-
e && (
|
|
323
|
+
e && (n?.chain().focus("end").insertContent(e).run(), n && x(n));
|
|
321
324
|
}
|
|
322
|
-
}), [
|
|
323
|
-
value:
|
|
324
|
-
children: [/* @__PURE__ */ O(
|
|
325
|
-
editor:
|
|
326
|
-
className:
|
|
325
|
+
}), [n, b]), /* @__PURE__ */ De(Ee, {
|
|
326
|
+
value: J,
|
|
327
|
+
children: [/* @__PURE__ */ O(ae, {
|
|
328
|
+
editor: n,
|
|
329
|
+
className: G(w.root, o),
|
|
327
330
|
"data-rich-input-menu": h?.items.length ? "" : void 0
|
|
328
331
|
}), /* @__PURE__ */ O(Te, {
|
|
329
332
|
isOpen: !!h?.items.length,
|
|
@@ -335,11 +338,11 @@ function Qe({
|
|
|
335
338
|
onSelect: (e) => {
|
|
336
339
|
if (e.action) {
|
|
337
340
|
e.action({
|
|
338
|
-
setItems: (l) =>
|
|
341
|
+
setItems: (l) => r.setMenuItems(l)
|
|
339
342
|
});
|
|
340
343
|
return;
|
|
341
344
|
}
|
|
342
|
-
h?.command(e),
|
|
345
|
+
h?.command(e), r.setMenu(null);
|
|
343
346
|
}
|
|
344
347
|
})]
|
|
345
348
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichInput.js","sources":["../../src/RichInput/RichInput.tsx"],"sourcesContent":["'use client';\n\nimport { clamp, cn } from '@reforma/lib';\nimport { mergeAttributes } from '@tiptap/core';\nimport Bold from '@tiptap/extension-bold';\nimport Code from '@tiptap/extension-code';\nimport Document from '@tiptap/extension-document';\nimport HardBreak from '@tiptap/extension-hard-break';\nimport History from '@tiptap/extension-history';\nimport Italic from '@tiptap/extension-italic';\nimport { ListKit, OrderedList } from '@tiptap/extension-list';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Text from '@tiptap/extension-text';\nimport { PluginKey } from '@tiptap/pm/state';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport {\n createElement,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport {\n docsEqual,\n docToPlainText,\n emptyComposerDoc,\n mentionNodes,\n pastedTextToMentionContent,\n} from './composerDoc';\nimport { handleComposerKeyDown } from './composerKeymap';\nimport { ComposerMention } from './composerMention';\nimport { defaultRenderMention, defaultSerializeMention, mentionAttrsFromNode, RichInputMentionContext } from './mentionRender';\nimport styles from './RichInput.module.css';\nimport { RichInputTriggerMenu, type RichInputTriggerAnchor } from './RichInputTriggerMenu';\n\nimport type { SuggestionKeyDownProps, SuggestionProps } from '@tiptap/suggestion';\nimport type {\n ComposerDoc,\n ComposerMentionAttrs,\n RichInputHandle,\n RichInputMentionRenderer,\n RichInputMentionSerializer,\n RichInputTrigger,\n RichInputTriggerItem,\n RichInputTriggerPlacement,\n} from './types';\n\nexport type RichInputProps = {\n value?: ComposerDoc;\n onChange?: (doc: ComposerDoc) => void;\n triggers?: readonly RichInputTrigger[];\n /**\n * How to paint an inline mention/command atom. TipTap NodeViews portal under\n * {@link EditorContent}, so this is provided via context (not extension config).\n * Default: plain label text.\n */\n renderMention?: RichInputMentionRenderer;\n /**\n * Plain-text form of a mention for copy/paste and {@link docToPlainText}.\n * Default: omit (`''`) — chips are atoms, not typed characters.\n */\n serializeMention?: RichInputMentionSerializer;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n /** Markdown input rules: bold/italic/code, lists (`- ` / `1. `). Default true. */\n markdown?: boolean;\n autoFocus?: boolean;\n minHeight?: number;\n maxHeight?: number;\n /** Enter submits. Default false — Enter starts a new paragraph; Cmd/Ctrl+Enter submits when `onSubmit` is set. */\n submitOnEnter?: boolean;\n 'aria-label'?: string;\n onSubmit?: (doc: ComposerDoc, origin?: { mod: boolean }) => void;\n onEscape?: () => void;\n onPasteFiles?: (files: File[]) => void;\n /**\n * Plain-text paste hook. Return true to consume the paste (no doc insert).\n * File pastes are handled by {@link onPasteFiles} first.\n */\n onPasteText?: (text: string) => boolean;\n id?: string;\n ref?: Ref<RichInputHandle>;\n};\n\ntype MenuState = {\n char: string;\n accessibilityLabel: string;\n items: RichInputTriggerItem[];\n selectedKey: string | null;\n anchor: RichInputTriggerAnchor;\n placement: RichInputTriggerPlacement;\n command: (item: RichInputTriggerItem) => void;\n};\n\ntype Bridge = {\n triggers: readonly RichInputTrigger[];\n submitOnEnter: boolean;\n onChange?: (doc: ComposerDoc) => void;\n onPasteFiles?: (files: File[]) => void;\n onPasteText?: (text: string) => boolean;\n renderMention?: RichInputMentionRenderer;\n serializeMention?: RichInputMentionSerializer;\n onSubmit?: (doc: ComposerDoc, origin?: { mod: boolean }) => void;\n onEscape?: () => void;\n setMenu: (menu: MenuState | null) => void;\n getMenu: () => MenuState | null;\n setMenuItems: (items: RichInputTriggerItem[]) => void;\n getEditorDoc: () => ComposerDoc;\n insertContent: (content: ComposerDoc | ComposerDoc[]) => void;\n};\n\nconst EMPTY_TRIGGERS: readonly RichInputTrigger[] = [];\n\nfunction createBridge(setMenu: (menu: MenuState | null) => void): Bridge {\n let menu: MenuState | null = null;\n\n const bridge: Bridge = {\n triggers: EMPTY_TRIGGERS,\n submitOnEnter: false,\n getMenu: () => menu,\n setMenu: (next) => {\n menu = next;\n setMenu(next);\n },\n setMenuItems: (items) => {\n const current = menu;\n\n if (!current) {\n return;\n }\n\n menu = {\n ...current,\n items,\n selectedKey: items.some(i => i.value === current.selectedKey)\n ? current.selectedKey\n : (items[0]?.value ?? null),\n };\n setMenu(menu);\n },\n getEditorDoc: () => emptyComposerDoc(),\n insertContent: () => undefined,\n };\n\n return bridge;\n}\n\nfunction triggerAnchor(\n trigger: RichInputTrigger,\n caret: DOMRect | null | undefined,\n fallback?: RichInputTriggerAnchor\n): RichInputTriggerAnchor {\n const host = trigger.getAnchorRect?.();\n\n if (host) {\n return { x: host.left, top: host.top, bottom: host.bottom, width: host.width };\n }\n\n if (caret) {\n return { x: caret.left, top: caret.top, bottom: caret.bottom };\n }\n\n return fallback ?? { x: 0, top: 0, bottom: 0 };\n}\n\nfunction buildSuggestionRender(bridge: Bridge, triggerChar: string) {\n return () => {\n let activeChar = triggerChar;\n let searchSeq = 0;\n\n const runSearch = (trigger: RichInputTrigger, query: string) => {\n const seq = ++searchSeq;\n\n void Promise.resolve(trigger.onSearch(query)).then((items) => {\n if (seq !== searchSeq) {\n return;\n }\n\n bridge.setMenuItems(items);\n });\n };\n\n return {\n onStart: (props: SuggestionProps<RichInputTriggerItem>) => {\n const match = bridge.triggers.find(t => t.char === activeChar);\n const rect = props.clientRect?.();\n\n if (!match) {\n return;\n }\n\n activeChar = match.char;\n bridge.setMenu({\n char: match.char,\n accessibilityLabel: match.accessibilityLabel,\n items: [],\n selectedKey: null,\n placement: match.placement ?? 'auto',\n anchor: triggerAnchor(match, rect),\n command: item => props.command(item),\n });\n runSearch(match, props.query);\n },\n onUpdate: (props: SuggestionProps<RichInputTriggerItem>) => {\n const match = bridge.triggers.find(t => t.char === activeChar);\n const rect = props.clientRect?.();\n const current = bridge.getMenu();\n\n if (!match || !current) {\n return;\n }\n\n bridge.setMenu({\n ...current,\n placement: match.placement ?? current.placement,\n anchor: triggerAnchor(match, rect, current.anchor),\n command: item => props.command(item),\n });\n runSearch(match, props.query);\n },\n onExit: () => {\n searchSeq += 1;\n bridge.triggers.find(t => t.char === activeChar)?.onClose?.();\n bridge.setMenu(null);\n },\n onKeyDown: ({ event }: SuggestionKeyDownProps) => {\n const current = bridge.getMenu();\n\n if (!current) {\n return false;\n }\n\n if (event.key === 'Escape') {\n if (current.items.length === 0) {\n return false;\n }\n\n bridge.setMenu(null);\n\n return true;\n }\n\n if ((event.key === 'ArrowDown' || event.key === 'ArrowUp') && current.items.length > 0) {\n const index = current.items.findIndex(i => i.value === current.selectedKey);\n const next = event.key === 'ArrowDown'\n ? current.items[Math.min(index + 1, current.items.length - 1)]\n : current.items[Math.max(index - 1, 0)];\n\n bridge.setMenu({ ...current, selectedKey: next?.value ?? null });\n\n return true;\n }\n\n if ((event.key === 'Enter' || event.key === 'Tab' || event.key === ' ') && current.items.length > 0) {\n const item = current.items.find(i => i.value === current.selectedKey) ?? current.items[0];\n\n if (!item) {\n return false;\n }\n\n if (event.key === ' ' && item.kind !== 'link') {\n return false;\n }\n\n if (item.action) {\n item.action({\n setItems: items => bridge.setMenuItems(items),\n });\n\n return true;\n }\n\n current.command(item);\n\n return true;\n }\n\n return false;\n },\n };\n };\n}\n\nconst FOREIGN_TEXT_ENTRY = [\n 'textarea',\n 'input:not([type=\"hidden\"])',\n '[contenteditable]:not([contenteditable=\"false\"])',\n '.cm-editor',\n '.monaco-editor',\n].join(', ');\n\ntype MountedEditor = {\n isDestroyed: boolean;\n view: { dom: Element };\n};\n\nfunction mountedEditorDom(editor: MountedEditor | null): Element | null {\n if (!editor || editor.isDestroyed) {\n return null;\n }\n\n try {\n return editor.view.dom;\n }\n catch {\n return null;\n }\n}\n\nfunction isTextEntry(active: Element): boolean {\n if (active.closest(FOREIGN_TEXT_ENTRY)) {\n return true;\n }\n\n if (!(active instanceof HTMLIFrameElement)) {\n return false;\n }\n\n try {\n const inner = active.contentDocument?.activeElement;\n\n return Boolean(\n inner\n && inner !== active.contentDocument?.body\n && inner !== active.contentDocument?.documentElement\n && inner.closest(FOREIGN_TEXT_ENTRY)\n );\n }\n catch {\n return false;\n }\n}\n\n/**\n * An editor recreate (placeholder changes when a turn ends) must not pull focus\n * out of a comment, code editor, or other field. First mount has no root yet and still autofocuses.\n */\nexport function shouldYieldRichInputAutofocus(ownRoot: Element | null): boolean {\n if (!ownRoot || typeof document === 'undefined') {\n return false;\n }\n\n const active = document.activeElement;\n\n if (!active || active === document.body || active === document.documentElement) {\n return false;\n }\n\n if (active === ownRoot || ownRoot.contains(active)) {\n return false;\n }\n\n return isTextEntry(active);\n}\n\n/**\n * TipTap composer input. Inline mention chrome comes from {@link RichInputProps.renderMention}.\n */\nexport function RichInput({\n value,\n onChange,\n triggers = EMPTY_TRIGGERS,\n renderMention,\n serializeMention,\n placeholder = '',\n className,\n disabled,\n markdown = true,\n autoFocus,\n minHeight = 24,\n maxHeight,\n submitOnEnter = false,\n 'aria-label': ariaLabel,\n onSubmit,\n onEscape,\n onPasteFiles,\n onPasteText,\n id,\n ref,\n}: RichInputProps): ReactNode {\n const [menu, setMenu] = useState<MenuState | null>(null);\n const [getBridge] = useState(() => {\n const live = createBridge(setMenu);\n\n return () => live;\n });\n const bridge = getBridge();\n // Stable for TipTap portals — always delegates to the latest prop / default.\n // Must `createElement` (not call): front `observer`/compiler wrappers are objects.\n const [mentionRenderer] = useState(() => {\n const render: RichInputMentionRenderer = (props) => {\n const Impl = getBridge().renderMention ?? defaultRenderMention;\n\n return createElement(Impl, props);\n };\n\n return render;\n });\n /** Last caret pos — used when pinning layers/files while the editor is blurred. */\n const lastPosRef = useRef(1);\n\n const rememberPos = (tipTapEditor: { state: { selection: { head: number } } }) => {\n lastPosRef.current = tipTapEditor.state.selection.head;\n };\n\n bridge.triggers = triggers;\n bridge.submitOnEnter = submitOnEnter;\n bridge.onChange = onChange;\n bridge.onPasteFiles = onPasteFiles;\n bridge.onPasteText = onPasteText;\n bridge.renderMention = renderMention;\n bridge.serializeMention = serializeMention;\n bridge.onSubmit = onSubmit;\n bridge.onEscape = onEscape;\n\n const triggerKey = triggers.map(t => `${ t.char }:${ t.position ?? 'any' }`).join('|');\n // Previous editor root, so a recreate can see where focus was before TipTap swaps the DOM.\n const [yieldRoot, setYieldRoot] = useState<Element | null>(null);\n\n const editor = useEditor({\n immediatelyRender: false,\n editable: !disabled,\n autofocus: autoFocus && !shouldYieldRichInputAutofocus(yieldRoot)\n ? 'end'\n : false,\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak.extend({\n addKeyboardShortcuts() {\n return {};\n },\n }),\n History,\n ...(markdown\n ? [\n Bold,\n Italic,\n Code,\n ListKit.configure({ orderedList: false, taskItem: false, taskList: false }),\n OrderedList.extend({\n // CSS draws the numbers (see `.editor ol`); seed the counter from `start`.\n renderHTML({ node, HTMLAttributes }) {\n return ['ol', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n style: `counter-reset: rich-input-ol ${ node.attrs.start - 1 }`,\n }), 0];\n },\n }),\n ]\n : []),\n Placeholder.configure({ placeholder }),\n ComposerMention.configure({\n // Backspace on a chip must not leave a stray `@` / `/` trigger char.\n deleteTriggerWithBackspace: true,\n renderText: ({ node }) => (\n (bridge.serializeMention ?? defaultSerializeMention)(\n mentionAttrsFromNode(node.attrs)\n )\n ),\n suggestions: triggers.map(trigger => ({\n char: trigger.char,\n pluginKey: new PluginKey(`rich-input-${ trigger.char }`),\n startOfLine: trigger.position === 'start',\n allowedPrefixes: trigger.position === 'start' ? null : undefined,\n items: () => [],\n render: buildSuggestionRender(bridge, trigger.char),\n command: ({ editor: tipTapEditor, range, props }) => {\n const item = props as unknown as RichInputTriggerItem;\n\n if (item.action) {\n return;\n }\n\n if (item.run) {\n tipTapEditor.chain().focus().deleteRange(range).run();\n item.run();\n\n return;\n }\n\n if (!item.kind) {\n return;\n }\n\n tipTapEditor\n .chain()\n .focus()\n .insertContentAt(range, mentionNodes({\n id: item.value,\n label: item.displayText ?? item.label,\n kind: item.kind,\n trigger: trigger.char,\n data: item.data,\n }))\n .run();\n },\n })),\n }),\n ],\n content: value ?? emptyComposerDoc(),\n editorProps: {\n attributes: {\n ...(id ? { id } : {}),\n ...(ariaLabel ? { 'aria-label': ariaLabel } : {}),\n class: styles.editor,\n style: [\n `min-height:${ minHeight }px`,\n maxHeight != null ? `max-height:${ maxHeight }px` : null,\n maxHeight != null ? 'overflow-y:auto' : null,\n ].filter(Boolean).join(';'),\n },\n handleKeyDown: (view, event) => handleComposerKeyDown(view, event, {\n submitOnEnter: bridge.submitOnEnter,\n hasMenuItems: Boolean(bridge.getMenu()?.items.length),\n onSubmit: origin => bridge.onSubmit?.(bridge.getEditorDoc(), origin),\n onEscape: bridge.onEscape,\n closeMenu: () => bridge.setMenu(null),\n }),\n handlePaste: (_view, event) => {\n const files = event.clipboardData?.files;\n\n if (files && files.length > 0 && bridge.onPasteFiles) {\n bridge.onPasteFiles([...files]);\n event.preventDefault();\n\n return true;\n }\n\n const text = event.clipboardData?.getData('text/plain') ?? '';\n\n if (text && bridge.onPasteText?.(text)) {\n event.preventDefault();\n\n return true;\n }\n\n const mention = bridge.triggers.find(trigger => trigger.char === '@');\n\n if (!mention || !text || !/@https?:\\/\\/\\S/i.test(text)) {\n return false;\n }\n\n event.preventDefault();\n void pastedTextToMentionContent(text, mention).then((content) => {\n bridge.setMenu(null);\n bridge.insertContent(content);\n });\n\n return true;\n },\n },\n onUpdate: ({ editor: tipTapEditor }) => {\n rememberPos(tipTapEditor);\n bridge.onChange?.(tipTapEditor.getJSON() as ComposerDoc);\n },\n onSelectionUpdate: ({ editor: tipTapEditor }) => {\n rememberPos(tipTapEditor);\n },\n onBlur: ({ editor: tipTapEditor }) => {\n rememberPos(tipTapEditor);\n },\n }, [triggerKey, markdown, placeholder]);\n\n useLayoutEffect(() => {\n setYieldRoot(mountedEditorDom(editor));\n }, [editor]);\n\n bridge.getEditorDoc = () => (\n (editor?.getJSON() as ComposerDoc | undefined) ?? emptyComposerDoc()\n );\n bridge.insertContent = (content) => {\n editor?.chain().focus().insertContent(content).run();\n };\n\n useLayoutEffect(() => {\n if (!editor || value == null) {\n return;\n }\n\n if (!docsEqual(editor.getJSON() as ComposerDoc, value)) {\n // External/controlled sync must not push history steps — otherwise Cmd+Z\n // undoes the sync, then the prop re-applies and undo looks broken.\n editor\n .chain()\n .setMeta('addToHistory', false)\n .setContent(value, { emitUpdate: false })\n .run();\n\n const pos = clamp(1, lastPosRef.current, editor.state.doc.content.size);\n\n lastPosRef.current = pos;\n\n if (editor.isFocused) {\n editor.commands.setTextSelection(pos);\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n editor?.setEditable(!disabled);\n }, [editor, disabled]);\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (!editor) {\n return;\n }\n\n const pos = clamp(1, lastPosRef.current, editor.state.doc.content.size);\n\n editor.chain().focus().setTextSelection(pos).run();\n },\n getDoc: () => (editor?.getJSON() as ComposerDoc) ?? emptyComposerDoc(),\n getPlainText: () => docToPlainText(\n (editor?.getJSON() as ComposerDoc) ?? emptyComposerDoc(),\n getBridge().serializeMention\n ),\n insertMention: (attrs: ComposerMentionAttrs) => {\n if (!editor) {\n return;\n }\n\n const pos = clamp(1, lastPosRef.current, editor.state.doc.content.size);\n\n editor\n .chain()\n .insertContentAt(pos, mentionNodes(attrs))\n .focus()\n .run();\n rememberPos(editor);\n },\n appendText: (text: string) => {\n if (!text) {\n return;\n }\n\n editor?.chain().focus('end').insertContent(text).run();\n if (editor) {\n rememberPos(editor);\n }\n },\n }), [editor, getBridge]);\n\n return (\n <RichInputMentionContext value={ mentionRenderer }>\n <EditorContent\n editor={ editor }\n className={ cn(styles.root, className) }\n data-rich-input-menu={ menu?.items.length ? '' : undefined }\n />\n <RichInputTriggerMenu\n isOpen={ Boolean(menu?.items.length) }\n anchor={ menu?.anchor ?? null }\n placement={ menu?.placement ?? 'auto' }\n items={ menu?.items ?? [] }\n selectedKey={ menu?.selectedKey ?? null }\n accessibilityLabel={ menu?.accessibilityLabel ?? 'Suggestions' }\n onSelect={ (item) => {\n if (item.action) {\n item.action({\n setItems: items => bridge.setMenuItems(items),\n });\n\n return;\n }\n\n menu?.command(item);\n bridge.setMenu(null);\n } }\n />\n </RichInputMentionContext>\n );\n}\n"],"names":["EMPTY_TRIGGERS","createBridge","setMenu","menu","next","items","current","i","emptyComposerDoc","triggerAnchor","trigger","caret","fallback","host","buildSuggestionRender","bridge","triggerChar","activeChar","searchSeq","runSearch","query","seq","props","match","t","rect","item","event","index","FOREIGN_TEXT_ENTRY","mountedEditorDom","editor","isTextEntry","active","inner","shouldYieldRichInputAutofocus","ownRoot","RichInput","value","onChange","triggers","renderMention","serializeMention","placeholder","className","disabled","markdown","autoFocus","minHeight","maxHeight","submitOnEnter","ariaLabel","onSubmit","onEscape","onPasteFiles","onPasteText","id","ref","useState","getBridge","live","mentionRenderer","Impl","defaultRenderMention","createElement","lastPosRef","useRef","rememberPos","tipTapEditor","triggerKey","yieldRoot","setYieldRoot","useEditor","Document","Paragraph","Text","HardBreak","History","Bold","Italic","Code","ListKit","OrderedList","node","HTMLAttributes","mergeAttributes","Placeholder","ComposerMention","defaultSerializeMention","mentionAttrsFromNode","PluginKey","range","mentionNodes","styles","view","handleComposerKeyDown","origin","_view","files","text","mention","pastedTextToMentionContent","content","useLayoutEffect","docsEqual","pos","clamp","useEffect","useImperativeHandle","docToPlainText","attrs","RichInputMentionContext","_jsx","EditorContent","cn","RichInputTriggerMenu"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RichInput.js","sources":["../../src/RichInput/RichInput.tsx"],"sourcesContent":["'use client';\n\nimport { clamp, cn } from '@reforma/lib';\nimport { mergeAttributes } from '@tiptap/core';\nimport Bold from '@tiptap/extension-bold';\nimport Code from '@tiptap/extension-code';\nimport Document from '@tiptap/extension-document';\nimport HardBreak from '@tiptap/extension-hard-break';\nimport History from '@tiptap/extension-history';\nimport Italic from '@tiptap/extension-italic';\nimport { ListKit, OrderedList } from '@tiptap/extension-list';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Text from '@tiptap/extension-text';\nimport { PluginKey } from '@tiptap/pm/state';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport {\n createElement,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport {\n docsEqual,\n docToPlainText,\n emptyComposerDoc,\n mentionNodes,\n pastedTextToMentionContent,\n} from './composerDoc';\nimport { handleComposerKeyDown } from './composerKeymap';\nimport { ComposerMention } from './composerMention';\nimport { defaultRenderMention, defaultSerializeMention, mentionAttrsFromNode, RichInputMentionContext } from './mentionRender';\nimport styles from './RichInput.module.css';\nimport { RichInputTriggerMenu, type RichInputTriggerAnchor } from './RichInputTriggerMenu';\n\nimport type { SuggestionKeyDownProps, SuggestionProps } from '@tiptap/suggestion';\nimport type {\n ComposerDoc,\n ComposerMentionAttrs,\n RichInputHandle,\n RichInputMentionRenderer,\n RichInputMentionSerializer,\n RichInputTrigger,\n RichInputTriggerItem,\n RichInputTriggerPlacement,\n} from './types';\n\nexport type RichInputProps = {\n value?: ComposerDoc;\n onChange?: (doc: ComposerDoc) => void;\n triggers?: readonly RichInputTrigger[];\n /**\n * How to paint an inline mention/command atom. TipTap NodeViews portal under\n * {@link EditorContent}, so this is provided via context (not extension config).\n * Default: plain label text.\n */\n renderMention?: RichInputMentionRenderer;\n /**\n * Plain-text form of a mention for copy/paste and {@link docToPlainText}.\n * Default: omit (`''`) — chips are atoms, not typed characters.\n */\n serializeMention?: RichInputMentionSerializer;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n /** Markdown input rules: bold/italic/code, lists (`- ` / `1. `). Default true. */\n markdown?: boolean;\n autoFocus?: boolean;\n minHeight?: number;\n maxHeight?: number;\n /** Enter submits. Default false — Enter starts a new paragraph; Cmd/Ctrl+Enter submits when `onSubmit` is set. */\n submitOnEnter?: boolean;\n 'aria-label'?: string;\n onSubmit?: (doc: ComposerDoc, origin?: { mod: boolean }) => void;\n onEscape?: () => void;\n onPasteFiles?: (files: File[]) => void;\n /**\n * Plain-text paste hook. Return true to consume the paste (no doc insert).\n * File pastes are handled by {@link onPasteFiles} first.\n */\n onPasteText?: (text: string) => boolean;\n id?: string;\n ref?: Ref<RichInputHandle>;\n};\n\ntype MenuState = {\n char: string;\n accessibilityLabel: string;\n items: RichInputTriggerItem[];\n selectedKey: string | null;\n anchor: RichInputTriggerAnchor;\n placement: RichInputTriggerPlacement;\n command: (item: RichInputTriggerItem) => void;\n};\n\ntype Bridge = {\n triggers: readonly RichInputTrigger[];\n submitOnEnter: boolean;\n placeholder: string;\n onChange?: (doc: ComposerDoc) => void;\n onPasteFiles?: (files: File[]) => void;\n onPasteText?: (text: string) => boolean;\n renderMention?: RichInputMentionRenderer;\n serializeMention?: RichInputMentionSerializer;\n onSubmit?: (doc: ComposerDoc, origin?: { mod: boolean }) => void;\n onEscape?: () => void;\n setMenu: (menu: MenuState | null) => void;\n getMenu: () => MenuState | null;\n setMenuItems: (items: RichInputTriggerItem[]) => void;\n getEditorDoc: () => ComposerDoc;\n insertContent: (content: ComposerDoc | ComposerDoc[]) => void;\n};\n\nconst EMPTY_TRIGGERS: readonly RichInputTrigger[] = [];\n\nfunction createBridge(setMenu: (menu: MenuState | null) => void): Bridge {\n let menu: MenuState | null = null;\n\n const bridge: Bridge = {\n triggers: EMPTY_TRIGGERS,\n submitOnEnter: false,\n placeholder: '',\n getMenu: () => menu,\n setMenu: (next) => {\n menu = next;\n setMenu(next);\n },\n setMenuItems: (items) => {\n const current = menu;\n\n if (!current) {\n return;\n }\n\n menu = {\n ...current,\n items,\n selectedKey: items.some(i => i.value === current.selectedKey)\n ? current.selectedKey\n : (items[0]?.value ?? null),\n };\n setMenu(menu);\n },\n getEditorDoc: () => emptyComposerDoc(),\n insertContent: () => undefined,\n };\n\n return bridge;\n}\n\nfunction triggerAnchor(\n trigger: RichInputTrigger,\n caret: DOMRect | null | undefined,\n fallback?: RichInputTriggerAnchor\n): RichInputTriggerAnchor {\n const host = trigger.getAnchorRect?.();\n\n if (host) {\n return { x: host.left, top: host.top, bottom: host.bottom, width: host.width };\n }\n\n if (caret) {\n return { x: caret.left, top: caret.top, bottom: caret.bottom };\n }\n\n return fallback ?? { x: 0, top: 0, bottom: 0 };\n}\n\nfunction buildSuggestionRender(bridge: Bridge, triggerChar: string) {\n return () => {\n let activeChar = triggerChar;\n let searchSeq = 0;\n\n const runSearch = (trigger: RichInputTrigger, query: string) => {\n const seq = ++searchSeq;\n\n void Promise.resolve(trigger.onSearch(query)).then((items) => {\n if (seq !== searchSeq) {\n return;\n }\n\n bridge.setMenuItems(items);\n });\n };\n\n return {\n onStart: (props: SuggestionProps<RichInputTriggerItem>) => {\n const match = bridge.triggers.find(t => t.char === activeChar);\n const rect = props.clientRect?.();\n\n if (!match) {\n return;\n }\n\n activeChar = match.char;\n bridge.setMenu({\n char: match.char,\n accessibilityLabel: match.accessibilityLabel,\n items: [],\n selectedKey: null,\n placement: match.placement ?? 'auto',\n anchor: triggerAnchor(match, rect),\n command: item => props.command(item),\n });\n runSearch(match, props.query);\n },\n onUpdate: (props: SuggestionProps<RichInputTriggerItem>) => {\n const match = bridge.triggers.find(t => t.char === activeChar);\n const rect = props.clientRect?.();\n const current = bridge.getMenu();\n\n if (!match || !current) {\n return;\n }\n\n bridge.setMenu({\n ...current,\n placement: match.placement ?? current.placement,\n anchor: triggerAnchor(match, rect, current.anchor),\n command: item => props.command(item),\n });\n runSearch(match, props.query);\n },\n onExit: () => {\n searchSeq += 1;\n bridge.triggers.find(t => t.char === activeChar)?.onClose?.();\n bridge.setMenu(null);\n },\n onKeyDown: ({ event }: SuggestionKeyDownProps) => {\n const current = bridge.getMenu();\n\n if (!current) {\n return false;\n }\n\n if (event.key === 'Escape') {\n if (current.items.length === 0) {\n return false;\n }\n\n bridge.setMenu(null);\n\n return true;\n }\n\n if ((event.key === 'ArrowDown' || event.key === 'ArrowUp') && current.items.length > 0) {\n const index = current.items.findIndex(i => i.value === current.selectedKey);\n const next = event.key === 'ArrowDown'\n ? current.items[Math.min(index + 1, current.items.length - 1)]\n : current.items[Math.max(index - 1, 0)];\n\n bridge.setMenu({ ...current, selectedKey: next?.value ?? null });\n\n return true;\n }\n\n if ((event.key === 'Enter' || event.key === 'Tab' || event.key === ' ') && current.items.length > 0) {\n const item = current.items.find(i => i.value === current.selectedKey) ?? current.items[0];\n\n if (!item) {\n return false;\n }\n\n if (event.key === ' ' && item.kind !== 'link') {\n return false;\n }\n\n if (item.action) {\n item.action({\n setItems: items => bridge.setMenuItems(items),\n });\n\n return true;\n }\n\n current.command(item);\n\n return true;\n }\n\n return false;\n },\n };\n };\n}\n\nconst FOREIGN_TEXT_ENTRY = [\n 'textarea',\n 'input:not([type=\"hidden\"])',\n '[contenteditable]:not([contenteditable=\"false\"])',\n '.cm-editor',\n '.monaco-editor',\n].join(', ');\n\ntype MountedEditor = {\n isDestroyed: boolean;\n view: { dom: Element };\n};\n\nfunction mountedEditorDom(editor: MountedEditor | null): Element | null {\n if (!editor || editor.isDestroyed) {\n return null;\n }\n\n try {\n return editor.view.dom;\n }\n catch {\n return null;\n }\n}\n\nfunction isTextEntry(active: Element): boolean {\n if (active.closest(FOREIGN_TEXT_ENTRY)) {\n return true;\n }\n\n if (!(active instanceof HTMLIFrameElement)) {\n return false;\n }\n\n try {\n const inner = active.contentDocument?.activeElement;\n\n return Boolean(\n inner\n && inner !== active.contentDocument?.body\n && inner !== active.contentDocument?.documentElement\n && inner.closest(FOREIGN_TEXT_ENTRY)\n );\n }\n catch {\n return false;\n }\n}\n\n/**\n * An editor recreate (triggers or markdown change) must not pull focus\n * out of a comment, code editor, or other field. First mount has no root yet and still autofocuses.\n */\nexport function shouldYieldRichInputAutofocus(ownRoot: Element | null): boolean {\n if (!ownRoot || typeof document === 'undefined') {\n return false;\n }\n\n const active = document.activeElement;\n\n if (!active || active === document.body || active === document.documentElement) {\n return false;\n }\n\n if (active === ownRoot || ownRoot.contains(active)) {\n return false;\n }\n\n return isTextEntry(active);\n}\n\n/**\n * TipTap composer input. Inline mention chrome comes from {@link RichInputProps.renderMention}.\n */\nexport function RichInput({\n value,\n onChange,\n triggers = EMPTY_TRIGGERS,\n renderMention,\n serializeMention,\n placeholder = '',\n className,\n disabled,\n markdown = true,\n autoFocus,\n minHeight = 24,\n maxHeight,\n submitOnEnter = false,\n 'aria-label': ariaLabel,\n onSubmit,\n onEscape,\n onPasteFiles,\n onPasteText,\n id,\n ref,\n}: RichInputProps): ReactNode {\n const [menu, setMenu] = useState<MenuState | null>(null);\n const [getBridge] = useState(() => {\n const live = createBridge(setMenu);\n\n return () => live;\n });\n const bridge = getBridge();\n // Stable for TipTap portals — always delegates to the latest prop / default.\n // Must `createElement` (not call): front `observer`/compiler wrappers are objects.\n const [mentionRenderer] = useState(() => {\n const render: RichInputMentionRenderer = (props) => {\n const Impl = getBridge().renderMention ?? defaultRenderMention;\n\n return createElement(Impl, props);\n };\n\n return render;\n });\n /** Last caret pos — used when pinning layers/files while the editor is blurred. */\n const lastPosRef = useRef(1);\n\n const rememberPos = (tipTapEditor: { state: { selection: { head: number } } }) => {\n lastPosRef.current = tipTapEditor.state.selection.head;\n };\n\n bridge.triggers = triggers;\n bridge.submitOnEnter = submitOnEnter;\n bridge.placeholder = placeholder;\n bridge.onChange = onChange;\n bridge.onPasteFiles = onPasteFiles;\n bridge.onPasteText = onPasteText;\n bridge.renderMention = renderMention;\n bridge.serializeMention = serializeMention;\n bridge.onSubmit = onSubmit;\n bridge.onEscape = onEscape;\n\n const triggerKey = triggers.map(t => `${ t.char }:${ t.position ?? 'any' }`).join('|');\n // Previous editor root, so a recreate can see where focus was before TipTap swaps the DOM.\n const [yieldRoot, setYieldRoot] = useState<Element | null>(null);\n\n const editor = useEditor({\n immediatelyRender: false,\n editable: !disabled,\n autofocus: autoFocus && !shouldYieldRichInputAutofocus(yieldRoot)\n ? 'end'\n : false,\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak.extend({\n addKeyboardShortcuts() {\n return {};\n },\n }),\n History,\n ...(markdown\n ? [\n Bold,\n Italic,\n Code,\n ListKit.configure({ orderedList: false, taskItem: false, taskList: false }),\n OrderedList.extend({\n // CSS draws the numbers (see `.editor ol`); seed the counter from `start`.\n renderHTML({ node, HTMLAttributes }) {\n return ['ol', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n style: `counter-reset: rich-input-ol ${ node.attrs.start - 1 }`,\n }), 0];\n },\n }),\n ]\n : []),\n Placeholder.configure({ placeholder: () => bridge.placeholder }),\n ComposerMention.configure({\n // Backspace on a chip must not leave a stray `@` / `/` trigger char.\n deleteTriggerWithBackspace: true,\n renderText: ({ node }) => (\n (bridge.serializeMention ?? defaultSerializeMention)(\n mentionAttrsFromNode(node.attrs)\n )\n ),\n suggestions: triggers.map(trigger => ({\n char: trigger.char,\n pluginKey: new PluginKey(`rich-input-${ trigger.char }`),\n startOfLine: trigger.position === 'start',\n allowedPrefixes: trigger.position === 'start' ? null : undefined,\n items: () => [],\n render: buildSuggestionRender(bridge, trigger.char),\n command: ({ editor: tipTapEditor, range, props }) => {\n const item = props as unknown as RichInputTriggerItem;\n\n if (item.action) {\n return;\n }\n\n if (item.run) {\n tipTapEditor.chain().focus().deleteRange(range).run();\n item.run();\n\n return;\n }\n\n if (!item.kind) {\n return;\n }\n\n tipTapEditor\n .chain()\n .focus()\n .insertContentAt(range, mentionNodes({\n id: item.value,\n label: item.displayText ?? item.label,\n kind: item.kind,\n trigger: trigger.char,\n data: item.data,\n }))\n .run();\n },\n })),\n }),\n ],\n content: value ?? emptyComposerDoc(),\n editorProps: {\n attributes: {\n ...(id ? { id } : {}),\n ...(ariaLabel ? { 'aria-label': ariaLabel } : {}),\n class: styles.editor,\n style: [\n `min-height:${ minHeight }px`,\n maxHeight != null ? `max-height:${ maxHeight }px` : null,\n maxHeight != null ? 'overflow-y:auto' : null,\n ].filter(Boolean).join(';'),\n },\n handleKeyDown: (view, event) => handleComposerKeyDown(view, event, {\n submitOnEnter: bridge.submitOnEnter,\n hasMenuItems: Boolean(bridge.getMenu()?.items.length),\n onSubmit: origin => bridge.onSubmit?.(bridge.getEditorDoc(), origin),\n onEscape: bridge.onEscape,\n closeMenu: () => bridge.setMenu(null),\n }),\n handlePaste: (_view, event) => {\n const files = event.clipboardData?.files;\n\n if (files && files.length > 0 && bridge.onPasteFiles) {\n bridge.onPasteFiles([...files]);\n event.preventDefault();\n\n return true;\n }\n\n const text = event.clipboardData?.getData('text/plain') ?? '';\n\n if (text && bridge.onPasteText?.(text)) {\n event.preventDefault();\n\n return true;\n }\n\n const mention = bridge.triggers.find(trigger => trigger.char === '@');\n\n if (!mention || !text || !/@https?:\\/\\/\\S/i.test(text)) {\n return false;\n }\n\n event.preventDefault();\n void pastedTextToMentionContent(text, mention).then((content) => {\n bridge.setMenu(null);\n bridge.insertContent(content);\n });\n\n return true;\n },\n },\n onUpdate: ({ editor: tipTapEditor }) => {\n rememberPos(tipTapEditor);\n bridge.onChange?.(tipTapEditor.getJSON() as ComposerDoc);\n },\n onSelectionUpdate: ({ editor: tipTapEditor }) => {\n rememberPos(tipTapEditor);\n },\n onBlur: ({ editor: tipTapEditor }) => {\n rememberPos(tipTapEditor);\n },\n }, [triggerKey, markdown]);\n\n useLayoutEffect(() => {\n setYieldRoot(mountedEditorDom(editor));\n }, [editor]);\n\n bridge.getEditorDoc = () => (\n (editor?.getJSON() as ComposerDoc | undefined) ?? emptyComposerDoc()\n );\n bridge.insertContent = (content) => {\n editor?.chain().focus().insertContent(content).run();\n };\n\n useLayoutEffect(() => {\n if (!editor || value == null) {\n return;\n }\n\n if (!docsEqual(editor.getJSON() as ComposerDoc, value)) {\n // External/controlled sync must not push history steps — otherwise Cmd+Z\n // undoes the sync, then the prop re-applies and undo looks broken.\n editor\n .chain()\n .setMeta('addToHistory', false)\n .setContent(value, { emitUpdate: false })\n .run();\n\n const pos = clamp(1, lastPosRef.current, editor.state.doc.content.size);\n\n lastPosRef.current = pos;\n\n if (editor.isFocused) {\n editor.commands.setTextSelection(pos);\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n editor?.setEditable(!disabled);\n }, [editor, disabled]);\n\n // Redraw the placeholder decoration in place; recreating the editor would drop focus.\n useEffect(() => {\n if (editor && !editor.isDestroyed) {\n editor.view.dispatch(editor.state.tr);\n }\n }, [editor, placeholder]);\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (!editor) {\n return;\n }\n\n const pos = clamp(1, lastPosRef.current, editor.state.doc.content.size);\n\n editor.chain().focus().setTextSelection(pos).run();\n },\n getDoc: () => (editor?.getJSON() as ComposerDoc) ?? emptyComposerDoc(),\n getPlainText: () => docToPlainText(\n (editor?.getJSON() as ComposerDoc) ?? emptyComposerDoc(),\n getBridge().serializeMention\n ),\n insertMention: (attrs: ComposerMentionAttrs) => {\n if (!editor) {\n return;\n }\n\n const pos = clamp(1, lastPosRef.current, editor.state.doc.content.size);\n\n editor\n .chain()\n .insertContentAt(pos, mentionNodes(attrs))\n .focus()\n .run();\n rememberPos(editor);\n },\n appendText: (text: string) => {\n if (!text) {\n return;\n }\n\n editor?.chain().focus('end').insertContent(text).run();\n if (editor) {\n rememberPos(editor);\n }\n },\n }), [editor, getBridge]);\n\n return (\n <RichInputMentionContext value={ mentionRenderer }>\n <EditorContent\n editor={ editor }\n className={ cn(styles.root, className) }\n data-rich-input-menu={ menu?.items.length ? '' : undefined }\n />\n <RichInputTriggerMenu\n isOpen={ Boolean(menu?.items.length) }\n anchor={ menu?.anchor ?? null }\n placement={ menu?.placement ?? 'auto' }\n items={ menu?.items ?? [] }\n selectedKey={ menu?.selectedKey ?? null }\n accessibilityLabel={ menu?.accessibilityLabel ?? 'Suggestions' }\n onSelect={ (item) => {\n if (item.action) {\n item.action({\n setItems: items => bridge.setMenuItems(items),\n });\n\n return;\n }\n\n menu?.command(item);\n bridge.setMenu(null);\n } }\n />\n </RichInputMentionContext>\n );\n}\n"],"names":["EMPTY_TRIGGERS","createBridge","setMenu","menu","next","items","current","i","emptyComposerDoc","triggerAnchor","trigger","caret","fallback","host","buildSuggestionRender","bridge","triggerChar","activeChar","searchSeq","runSearch","query","seq","props","match","t","rect","item","event","index","FOREIGN_TEXT_ENTRY","mountedEditorDom","editor","isTextEntry","active","inner","shouldYieldRichInputAutofocus","ownRoot","RichInput","value","onChange","triggers","renderMention","serializeMention","placeholder","className","disabled","markdown","autoFocus","minHeight","maxHeight","submitOnEnter","ariaLabel","onSubmit","onEscape","onPasteFiles","onPasteText","id","ref","useState","getBridge","live","mentionRenderer","Impl","defaultRenderMention","createElement","lastPosRef","useRef","rememberPos","tipTapEditor","triggerKey","yieldRoot","setYieldRoot","useEditor","Document","Paragraph","Text","HardBreak","History","Bold","Italic","Code","ListKit","OrderedList","node","HTMLAttributes","mergeAttributes","Placeholder","ComposerMention","defaultSerializeMention","mentionAttrsFromNode","PluginKey","range","mentionNodes","styles","view","handleComposerKeyDown","origin","_view","files","text","mention","pastedTextToMentionContent","content","useLayoutEffect","docsEqual","pos","clamp","useEffect","useImperativeHandle","docToPlainText","attrs","RichInputMentionContext","_jsx","EditorContent","cn","RichInputTriggerMenu"],"mappings":"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"}
|