@bikdotai/bik-component-library 0.0.853-beta.0 → 0.0.853

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 (145) hide show
  1. package/dist/cjs/components/agent-builder/AgentBuilder.js +1 -1
  2. package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
  3. package/dist/cjs/components/agent-builder/components/AgentBuilderFooter.js +1 -1
  4. package/dist/cjs/components/agent-builder/components/AgentBuilderFooter.js.map +1 -1
  5. package/dist/cjs/components/agent-builder/components/AgentBuilderTopBar.js +1 -1
  6. package/dist/cjs/components/agent-builder/components/AgentBuilderTopBar.js.map +1 -1
  7. package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js +11 -11
  8. package/dist/cjs/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
  9. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +5 -5
  10. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  11. package/dist/cjs/components/agent-builder/components/GoLiveModal.js +1 -1
  12. package/dist/cjs/components/agent-builder/components/GoLiveModal.js.map +1 -1
  13. package/dist/cjs/components/agent-builder/components/MentionEditor.js +1 -7
  14. package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
  15. package/dist/cjs/components/agent-builder/components/MentionField.js +1 -1
  16. package/dist/cjs/components/agent-builder/components/MentionField.js.map +1 -1
  17. package/dist/cjs/components/agent-builder/components/MentionPicker.js +26 -53
  18. package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
  19. package/dist/cjs/components/agent-builder/components/RequireVerificationModal.js +1 -1
  20. package/dist/cjs/components/agent-builder/components/RequireVerificationModal.js.map +1 -1
  21. package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js +5 -6
  22. package/dist/cjs/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
  23. package/dist/cjs/components/agent-builder/components/SelectableListSection.js +1 -1
  24. package/dist/cjs/components/agent-builder/components/SelectableListSection.js.map +1 -1
  25. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
  26. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  27. package/dist/cjs/components/agent-builder/constants/tools.js +1 -1
  28. package/dist/cjs/components/agent-builder/constants/tools.js.map +1 -1
  29. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
  30. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  31. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
  32. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  33. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +4 -4
  34. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  35. package/dist/cjs/components/agent-builder/utils/sourceIcons.js +1 -1
  36. package/dist/cjs/components/agent-builder/utils/sourceIcons.js.map +1 -1
  37. package/dist/cjs/components/agent-listing/AgentTableRow.js +1 -1
  38. package/dist/cjs/components/agent-listing/AgentTableRow.js.map +1 -1
  39. package/dist/cjs/components/agent-listing/AiAgentsEmptyState.js +1 -1
  40. package/dist/cjs/components/agent-listing/AiAgentsEmptyState.js.map +1 -1
  41. package/dist/cjs/components/variable-picker-v3/Content.js +1 -1
  42. package/dist/cjs/components/variable-picker-v3/Content.js.map +1 -1
  43. package/dist/cjs/components/zeroState/ZeroState.js +3 -3
  44. package/dist/cjs/components/zeroState/ZeroState.js.map +1 -1
  45. package/dist/cjs/editor/BikEditor.js +1 -1
  46. package/dist/cjs/editor/BikEditor.js.map +1 -1
  47. package/dist/cjs/editor/BikEditor.styles.js +21 -23
  48. package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
  49. package/dist/cjs/editor/BikEditor.types.js.map +1 -1
  50. package/dist/cjs/editor/extensions/jsonHighlight/JsonHighlightExtension.js +3 -3
  51. package/dist/cjs/editor/extensions/jsonHighlight/JsonHighlightExtension.js.map +1 -1
  52. package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
  53. package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
  54. package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
  55. package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
  56. package/dist/cjs/index.js +1 -1
  57. package/dist/esm/components/add-variableV2/index.d.ts +0 -1
  58. package/dist/esm/components/agent-builder/AgentBuilder.js +127 -119
  59. package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
  60. package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +7 -10
  61. package/dist/esm/components/agent-builder/components/AgentBuilderFooter.d.ts +2 -0
  62. package/dist/esm/components/agent-builder/components/AgentBuilderFooter.js +29 -26
  63. package/dist/esm/components/agent-builder/components/AgentBuilderFooter.js.map +1 -1
  64. package/dist/esm/components/agent-builder/components/AgentBuilderTopBar.js +30 -29
  65. package/dist/esm/components/agent-builder/components/AgentBuilderTopBar.js.map +1 -1
  66. package/dist/esm/components/agent-builder/components/ConfigToolPanel.d.ts +0 -8
  67. package/dist/esm/components/agent-builder/components/ConfigToolPanel.js +136 -182
  68. package/dist/esm/components/agent-builder/components/ConfigToolPanel.js.map +1 -1
  69. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.d.ts +9 -3
  70. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +230 -222
  71. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  72. package/dist/esm/components/agent-builder/components/GoLiveModal.js +11 -13
  73. package/dist/esm/components/agent-builder/components/GoLiveModal.js.map +1 -1
  74. package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +0 -12
  75. package/dist/esm/components/agent-builder/components/MentionEditor.js +103 -144
  76. package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
  77. package/dist/esm/components/agent-builder/components/MentionField.js +45 -48
  78. package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
  79. package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +1 -14
  80. package/dist/esm/components/agent-builder/components/MentionPicker.js +248 -292
  81. package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
  82. package/dist/esm/components/agent-builder/components/RequireVerificationModal.js +8 -8
  83. package/dist/esm/components/agent-builder/components/RequireVerificationModal.js.map +1 -1
  84. package/dist/esm/components/agent-builder/components/RestApiToolPanel.d.ts +0 -8
  85. package/dist/esm/components/agent-builder/components/RestApiToolPanel.js +172 -185
  86. package/dist/esm/components/agent-builder/components/RestApiToolPanel.js.map +1 -1
  87. package/dist/esm/components/agent-builder/components/SelectableListSection.js +73 -69
  88. package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
  89. package/dist/esm/components/agent-builder/components/ToolInstructionsField.d.ts +0 -9
  90. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +48 -67
  91. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  92. package/dist/esm/components/agent-builder/constants/tools.d.ts +21 -1
  93. package/dist/esm/components/agent-builder/constants/tools.js +33 -23
  94. package/dist/esm/components/agent-builder/constants/tools.js.map +1 -1
  95. package/dist/esm/components/agent-builder/context/AgentBuilderContext.d.ts +0 -7
  96. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +96 -99
  97. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  98. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +272 -261
  99. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  100. package/dist/esm/components/agent-builder/utils/mentionSerialization.d.ts +4 -14
  101. package/dist/esm/components/agent-builder/utils/mentionSerialization.js +36 -54
  102. package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  103. package/dist/esm/components/agent-builder/utils/sourceIcons.d.ts +6 -6
  104. package/dist/esm/components/agent-builder/utils/sourceIcons.js +21 -19
  105. package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -1
  106. package/dist/esm/components/agent-listing/AgentTableRow.js +26 -23
  107. package/dist/esm/components/agent-listing/AgentTableRow.js.map +1 -1
  108. package/dist/esm/components/agent-listing/AiAgentsEmptyState.js +3 -2
  109. package/dist/esm/components/agent-listing/AiAgentsEmptyState.js.map +1 -1
  110. package/dist/esm/components/variable-picker-v3/Content.js +15 -16
  111. package/dist/esm/components/variable-picker-v3/Content.js.map +1 -1
  112. package/dist/esm/components/zeroState/ZeroState.d.ts +2 -0
  113. package/dist/esm/components/zeroState/ZeroState.js +18 -17
  114. package/dist/esm/components/zeroState/ZeroState.js.map +1 -1
  115. package/dist/esm/editor/BikEditor.js +229 -222
  116. package/dist/esm/editor/BikEditor.js.map +1 -1
  117. package/dist/esm/editor/BikEditor.styles.js +14 -16
  118. package/dist/esm/editor/BikEditor.styles.js.map +1 -1
  119. package/dist/esm/editor/BikEditor.types.d.ts +0 -9
  120. package/dist/esm/editor/BikEditor.types.js.map +1 -1
  121. package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.js +62 -60
  122. package/dist/esm/editor/extensions/jsonHighlight/JsonHighlightExtension.js.map +1 -1
  123. package/dist/esm/editor/extensions/mention/MentionDropdown.js +28 -28
  124. package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
  125. package/dist/esm/editor/extensions/mention/MentionExtension.js +19 -23
  126. package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
  127. package/dist/esm/icons/index.d.ts +25 -25
  128. package/dist/esm/index.js +541 -543
  129. package/dist/esm/index.js.map +1 -1
  130. package/package.json +1 -1
  131. package/dist/cjs/components/add-variableV2/AddDataPill.js +0 -10
  132. package/dist/cjs/components/add-variableV2/AddDataPill.js.map +0 -1
  133. package/dist/cjs/components/agent-builder/components/VariableInlineField.js +0 -65
  134. package/dist/cjs/components/agent-builder/components/VariableInlineField.js.map +0 -1
  135. package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js +0 -10
  136. package/dist/cjs/components/agent-builder/components/VariableTriggerArea.js.map +0 -1
  137. package/dist/esm/components/add-variableV2/AddDataPill.d.ts +0 -24
  138. package/dist/esm/components/add-variableV2/AddDataPill.js +0 -33
  139. package/dist/esm/components/add-variableV2/AddDataPill.js.map +0 -1
  140. package/dist/esm/components/agent-builder/components/VariableInlineField.d.ts +0 -26
  141. package/dist/esm/components/agent-builder/components/VariableInlineField.js +0 -149
  142. package/dist/esm/components/agent-builder/components/VariableInlineField.js.map +0 -1
  143. package/dist/esm/components/agent-builder/components/VariableTriggerArea.d.ts +0 -46
  144. package/dist/esm/components/agent-builder/components/VariableTriggerArea.js +0 -118
  145. package/dist/esm/components/agent-builder/components/VariableTriggerArea.js.map +0 -1
@@ -1,7 +1,7 @@
1
- import { Extension as p } from "../../../node_modules/@tiptap/core/dist/index.js";
2
- import { Plugin as u, PluginKey as d, TextSelection as h } from "@tiptap/pm/state";
3
- import { Decoration as m, DecorationSet as f } from "@tiptap/pm/view";
4
- import { tokenizeJson as g } from "./tokenizeJson.js";
1
+ import { Extension as h } from "../../../node_modules/@tiptap/core/dist/index.js";
2
+ import { Plugin as u, PluginKey as d, TextSelection as p } from "@tiptap/pm/state";
3
+ import { Decoration as m, DecorationSet as g } from "@tiptap/pm/view";
4
+ import { tokenizeJson as f } from "./tokenizeJson.js";
5
5
  const k = {
6
6
  key: "bik-json-key",
7
7
  string: "bik-json-string",
@@ -10,40 +10,42 @@ const k = {
10
10
  null: "bik-json-null",
11
11
  punctuation: "bik-json-punct"
12
12
  };
13
- function b(r) {
14
- return r.trim().length === 0 ? 0 : r.split(`
13
+ function y(o) {
14
+ return o.trim().length === 0 ? 0 : o.split(`
15
15
  `).length;
16
16
  }
17
- class y {
17
+ class b {
18
18
  dom;
19
19
  contentDOM;
20
20
  gutter;
21
- constructor(n) {
22
- const t = document.createElement("pre"), e = document.createElement("div");
23
- e.className = "bik-json-gutter", e.contentEditable = "false";
24
- const o = document.createElement("code");
25
- t.appendChild(e), t.appendChild(o), this.dom = t, this.contentDOM = o, this.gutter = e, this.renderGutter(n);
21
+ constructor(e) {
22
+ const t = document.createElement("pre"), n = document.createElement("div");
23
+ n.className = "bik-json-gutter", n.contentEditable = "false";
24
+ const r = document.createElement("code");
25
+ t.appendChild(n), t.appendChild(r), this.dom = t, this.contentDOM = r, this.gutter = n, this.renderGutter(e);
26
26
  }
27
- renderGutter(n) {
28
- const t = b(n.textContent);
27
+ renderGutter(e) {
28
+ const t = y(e.textContent);
29
29
  if (this.gutter.childElementCount === t)
30
30
  return;
31
- const e = [];
32
- for (let o = 1; o <= t; o++) {
33
- const s = document.createElement("span");
34
- s.className = "bik-json-lineno", s.textContent = String(o), e.push(s);
31
+ const r = Math.max(2, String(Math.max(t, 1)).length) * 0.6 + 1.1;
32
+ this.gutter.style.width = `${r}em`, this.dom.style.paddingLeft = `${r + 0.7}em`;
33
+ const s = [];
34
+ for (let i = 1; i <= t; i++) {
35
+ const c = document.createElement("span");
36
+ c.className = "bik-json-lineno", c.textContent = String(i), s.push(c);
35
37
  }
36
- this.gutter.replaceChildren(...e);
38
+ this.gutter.replaceChildren(...s);
37
39
  }
38
- update(n) {
39
- return n.type.name !== "codeBlock" ? !1 : (this.renderGutter(n), !0);
40
+ update(e) {
41
+ return e.type.name !== "codeBlock" ? !1 : (this.renderGutter(e), !0);
40
42
  }
41
43
  // The gutter is ours to manage — never let ProseMirror parse it as content.
42
- ignoreMutation(n) {
43
- return this.gutter === n.target || this.gutter.contains(n.target);
44
+ ignoreMutation(e) {
45
+ return this.gutter === e.target || this.gutter.contains(e.target);
44
46
  }
45
47
  }
46
- const E = p.create({
48
+ const E = h.create({
47
49
  name: "jsonHighlight",
48
50
  // Above CodeBlock (default 100) so our Backspace handler runs first and can
49
51
  // veto CodeBlock's own "clearNodes at start" shortcut (which would lift the
@@ -58,8 +60,8 @@ const E = p.create({
58
60
  // deleting a leading `\n` from line 2+) still works — those have
59
61
  // parentOffset > 0.
60
62
  Backspace: () => {
61
- const { selection: r } = this.editor.state, { empty: n, $from: t } = r;
62
- return n && t.parent.type.name === "codeBlock" && t.parentOffset === 0;
63
+ const { selection: o } = this.editor.state, { empty: e, $from: t } = o;
64
+ return e && t.parent.type.name === "codeBlock" && t.parentOffset === 0;
63
65
  }
64
66
  };
65
67
  },
@@ -75,24 +77,24 @@ const E = p.create({
75
77
  // A paragraph has no gutter and no monospace rule, so the line numbers
76
78
  // and font vanish. Re-wrap the content back into a codeBlock whenever
77
79
  // something lifts it, restoring the invariant.
78
- appendTransaction(r, n, t) {
79
- if (!r.some((a) => a.docChanged))
80
+ appendTransaction(o, e, t) {
81
+ if (!o.some((a) => a.docChanged))
80
82
  return null;
81
- const { doc: e, schema: o } = t, s = o.nodes.codeBlock;
82
- if (!s || e.childCount === 1 && e.firstChild?.type === s)
83
+ const { doc: n, schema: r } = t, s = r.nodes.codeBlock;
84
+ if (!s || n.childCount === 1 && n.firstChild?.type === s)
83
85
  return null;
84
- let c = !1;
85
- if (e.forEach((a) => {
86
- a.type === s && (c = !0);
87
- }), c)
86
+ let i = !1;
87
+ if (n.forEach((a) => {
88
+ a.type === s && (i = !0);
89
+ }), i)
88
90
  return null;
89
- const l = e.textBetween(0, e.content.size, `
90
- `), i = t.tr;
91
- return i.replaceWith(
91
+ const c = n.textBetween(0, n.content.size, `
92
+ `), l = t.tr;
93
+ return l.replaceWith(
92
94
  0,
93
- e.content.size,
94
- s.create(null, l ? o.text(l) : null)
95
- ), i.setSelection(h.create(i.doc, 1)), i;
95
+ n.content.size,
96
+ s.create(null, c ? r.text(c) : null)
97
+ ), l.setSelection(p.create(l.doc, 1)), l;
96
98
  }
97
99
  }),
98
100
  new u({
@@ -101,44 +103,44 @@ const E = p.create({
101
103
  // The gutter is a node view, not a widget decoration — see
102
104
  // JsonCodeBlockView for why (MAP-7286).
103
105
  nodeViews: {
104
- codeBlock: (r) => new y(r)
106
+ codeBlock: (o) => new b(o)
105
107
  },
106
108
  // Paste beautify: if the clipboard text is valid JSON, drop in a
107
109
  // pretty-printed version (2-space indent, matching the Beautify
108
110
  // button) instead of the raw blob. Non-JSON pastes fall through to
109
111
  // the default handler untouched.
110
- handlePaste(r, n) {
111
- const t = n.clipboardData?.getData("text/plain");
112
+ handlePaste(o, e) {
113
+ const t = e.clipboardData?.getData("text/plain");
112
114
  if (!t || !t.trim())
113
115
  return !1;
114
- let e;
116
+ let n;
115
117
  try {
116
- e = JSON.parse(t);
118
+ n = JSON.parse(t);
117
119
  } catch {
118
120
  return !1;
119
121
  }
120
- const o = JSON.stringify(e, null, 2);
121
- if (o === t)
122
+ const r = JSON.stringify(n, null, 2);
123
+ if (r === t)
122
124
  return !1;
123
- const { state: s, dispatch: c } = r, { from: l, to: i } = s.selection;
124
- return c(s.tr.insertText(o, l, i).scrollIntoView()), !0;
125
+ const { state: s, dispatch: i } = o, { from: c, to: l } = s.selection;
126
+ return i(s.tr.insertText(r, c, l).scrollIntoView()), !0;
125
127
  },
126
128
  // Inline token colours only. Recolouring an inline span does not
127
129
  // disturb the caret (unlike the old gutter widgets).
128
- decorations(r) {
129
- const n = [];
130
- return r.doc.descendants((t, e) => {
130
+ decorations(o) {
131
+ const e = [];
132
+ return o.doc.descendants((t, n) => {
131
133
  if (t.type.name !== "codeBlock") return;
132
- const o = t.textContent;
133
- if (o.length === 0) return;
134
- const s = e + 1;
135
- for (const c of g(o))
136
- n.push(
137
- m.inline(s + c.start, s + c.end, {
138
- class: k[c.type]
134
+ const r = t.textContent;
135
+ if (r.length === 0) return;
136
+ const s = n + 1;
137
+ for (const i of f(r))
138
+ e.push(
139
+ m.inline(s + i.start, s + i.end, {
140
+ class: k[i.type]
139
141
  })
140
142
  );
141
- }), f.create(r.doc, n);
143
+ }), g.create(o.doc, e);
142
144
  }
143
145
  }
144
146
  })
@@ -1 +1 @@
1
- {"version":3,"file":"JsonHighlightExtension.js","sources":["../../../../../src/editor/extensions/jsonHighlight/JsonHighlightExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model';\nimport { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state';\nimport type { NodeView } from '@tiptap/pm/view';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport { JsonTokenType, tokenizeJson } from './tokenizeJson';\n\nconst CLASS_BY_TYPE: Record<JsonTokenType, string> = {\n\tkey: 'bik-json-key',\n\tstring: 'bik-json-string',\n\tnumber: 'bik-json-number',\n\tboolean: 'bik-json-boolean',\n\tnull: 'bik-json-null',\n\tpunctuation: 'bik-json-punct',\n};\n\n/**\n * Visual line count of a code block's text (0 → no gutter). Whitespace-only\n * content counts as 0: that's exactly when BikEditor shows the placeholder\n * overlay (`jsonEmpty = !text.trim()`), so the gutter must be empty too —\n * otherwise a blank field shows a stray \"1\" behind the placeholder.\n */\nfunction lineCount(text: string): number {\n\treturn text.trim().length === 0 ? 0 : text.split('\\n').length;\n}\n\n/**\n * Node view for the JSON `codeBlock` that renders the line-number gutter as a\n * `contenteditable=false` sibling of the editable `<code>` — NOT as ProseMirror\n * widget decorations.\n *\n * Why: widget decorations are re-inserted into the content flow on every\n * decoration recompute (i.e. every keystroke). Re-inserting a node next to the\n * caret reset the contenteditable selection to the line start, so typing a JSON\n * key and then its `:` dropped the caret to the start of the line (MAP-7286).\n * A node view lets us update the gutter DOM independently of `contentDOM`, so\n * the caret is never touched — and we only rebuild it when the line count\n * actually changes.\n */\nclass JsonCodeBlockView implements NodeView {\n\tdom: HTMLPreElement;\n\tcontentDOM: HTMLElement;\n\tprivate gutter: HTMLElement;\n\n\tconstructor(node: ProseMirrorNode) {\n\t\tconst pre = document.createElement('pre');\n\t\tconst gutter = document.createElement('div');\n\t\tgutter.className = 'bik-json-gutter';\n\t\tgutter.contentEditable = 'false';\n\t\tconst code = document.createElement('code');\n\t\t// Gutter is absolutely positioned into the reserved left padding, so its\n\t\t// order relative to <code> doesn't affect the code layout.\n\t\tpre.appendChild(gutter);\n\t\tpre.appendChild(code);\n\n\t\tthis.dom = pre;\n\t\tthis.contentDOM = code;\n\t\tthis.gutter = gutter;\n\t\tthis.renderGutter(node);\n\t}\n\n\tprivate renderGutter(node: ProseMirrorNode): void {\n\t\tconst count = lineCount(node.textContent);\n\t\t// Nothing to do while the line count is unchanged — this is the common case\n\t\t// (typing within a line) and skipping it avoids touching the gutter DOM.\n\t\tif (this.gutter.childElementCount === count) {\n\t\t\treturn;\n\t\t}\n\t\tconst numbers: HTMLElement[] = [];\n\t\tfor (let n = 1; n <= count; n++) {\n\t\t\tconst span = document.createElement('span');\n\t\t\tspan.className = 'bik-json-lineno';\n\t\t\tspan.textContent = String(n);\n\t\t\tnumbers.push(span);\n\t\t}\n\t\tthis.gutter.replaceChildren(...numbers);\n\t}\n\n\tupdate(node: ProseMirrorNode): boolean {\n\t\tif (node.type.name !== 'codeBlock') {\n\t\t\treturn false;\n\t\t}\n\t\tthis.renderGutter(node);\n\t\treturn true;\n\t}\n\n\t// The gutter is ours to manage — never let ProseMirror parse it as content.\n\tignoreMutation(mutation: MutationRecord | { target: Node }): boolean {\n\t\treturn (\n\t\t\tthis.gutter === mutation.target || this.gutter.contains(mutation.target)\n\t\t);\n\t}\n}\n\n/**\n * Colours JSON tokens inside `codeBlock` nodes and renders a line-number gutter\n * (via {@link JsonCodeBlockView}). A code block stores its whole multi-line body\n * in a single text node, so token offsets map 1:1 onto document positions\n * (`nodeStart + offset`) — no cross-node bookkeeping needed.\n *\n * Purely decorative: the document text is never rewritten, so undo/redo,\n * character count and the cursor all behave exactly as with plain text.\n */\nexport const JsonHighlightExtension = Extension.create({\n\tname: 'jsonHighlight',\n\t// Above CodeBlock (default 100) so our Backspace handler runs first and can\n\t// veto CodeBlock's own \"clearNodes at start\" shortcut (which would lift the\n\t// block to a paragraph).\n\tpriority: 1000,\n\taddKeyboardShortcuts() {\n\t\treturn {\n\t\t\t// In JSON mode the document is a single code block. A Backspace at its very\n\t\t\t// start would lift it to a plain paragraph (killing the highlight, the\n\t\t\t// line-number gutter and the monospace font). There's nothing to delete\n\t\t\t// before the caret there anyway, so swallow it. Mid-text Backspace (and\n\t\t\t// deleting a leading `\\n` from line 2+) still works — those have\n\t\t\t// parentOffset > 0.\n\t\t\tBackspace: () => {\n\t\t\t\tconst { selection } = this.editor.state;\n\t\t\t\tconst { empty, $from } = selection;\n\t\t\t\treturn (\n\t\t\t\t\tempty &&\n\t\t\t\t\t$from.parent.type.name === 'codeBlock' &&\n\t\t\t\t\t$from.parentOffset === 0\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlightGuard'),\n\t\t\t\t// jsonMode invariant: the whole document is ONE codeBlock. Several\n\t\t\t\t// default Backspace paths can lift it to a plain paragraph — and one\n\t\t\t\t// of them, TipTap core's `clearDocument` appendTransaction (fired when\n\t\t\t\t// the whole doc is selected then deleted, e.g. Cmd-A → Backspace),\n\t\t\t\t// runs AFTER our Backspace shortcut, so a keymap veto can't stop it.\n\t\t\t\t// A paragraph has no gutter and no monospace rule, so the line numbers\n\t\t\t\t// and font vanish. Re-wrap the content back into a codeBlock whenever\n\t\t\t\t// something lifts it, restoring the invariant.\n\t\t\t\tappendTransaction(transactions, _oldState, newState) {\n\t\t\t\t\tif (!transactions.some((tr) => tr.docChanged)) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst { doc, schema } = newState;\n\t\t\t\t\tconst codeBlock = schema.nodes['codeBlock'];\n\t\t\t\t\tif (!codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// Common case: already a single codeBlock → nothing to do.\n\t\t\t\t\tif (doc.childCount === 1 && doc.firstChild?.type === codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// If a codeBlock survives anywhere, leave it alone (don't fight\n\t\t\t\t\t// legitimate multi-node edits that shouldn't happen in jsonMode).\n\t\t\t\t\tlet hasCodeBlock = false;\n\t\t\t\t\tdoc.forEach((node) => {\n\t\t\t\t\t\tif (node.type === codeBlock) {\n\t\t\t\t\t\t\thasCodeBlock = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (hasCodeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// A lift happened: rebuild a single codeBlock from the text\n\t\t\t\t\t// (block boundaries preserved as newlines, matching JSON lines).\n\t\t\t\t\tconst text = doc.textBetween(0, doc.content.size, '\\n');\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\ttr.replaceWith(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\tdoc.content.size,\n\t\t\t\t\t\tcodeBlock.create(null, text ? schema.text(text) : null),\n\t\t\t\t\t);\n\t\t\t\t\ttr.setSelection(TextSelection.create(tr.doc, 1));\n\t\t\t\t\treturn tr;\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlight'),\n\t\t\t\tprops: {\n\t\t\t\t\t// The gutter is a node view, not a widget decoration — see\n\t\t\t\t\t// JsonCodeBlockView for why (MAP-7286).\n\t\t\t\t\tnodeViews: {\n\t\t\t\t\t\tcodeBlock: (node) => new JsonCodeBlockView(node),\n\t\t\t\t\t},\n\t\t\t\t\t// Paste beautify: if the clipboard text is valid JSON, drop in a\n\t\t\t\t\t// pretty-printed version (2-space indent, matching the Beautify\n\t\t\t\t\t// button) instead of the raw blob. Non-JSON pastes fall through to\n\t\t\t\t\t// the default handler untouched.\n\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\tconst raw = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!raw || !raw.trim()) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tvalue = JSON.parse(raw);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst pretty = JSON.stringify(value, null, 2);\n\t\t\t\t\t\t// No-op if it was already beautified (avoids a redundant tx).\n\t\t\t\t\t\tif (pretty === raw) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { state, dispatch } = view;\n\t\t\t\t\t\tconst { from, to } = state.selection;\n\t\t\t\t\t\tdispatch(state.tr.insertText(pretty, from, to).scrollIntoView());\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\t// Inline token colours only. Recolouring an inline span does not\n\t\t\t\t\t// disturb the caret (unlike the old gutter widgets).\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst decorations: Decoration[] = [];\n\t\t\t\t\t\tstate.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (node.type.name !== 'codeBlock') return;\n\t\t\t\t\t\t\tconst text = node.textContent;\n\t\t\t\t\t\t\tif (text.length === 0) return;\n\t\t\t\t\t\t\t// +1: step past the code-block node boundary into its text.\n\t\t\t\t\t\t\tconst base = pos + 1;\n\t\t\t\t\t\t\tfor (const tok of tokenizeJson(text)) {\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.inline(base + tok.start, base + tok.end, {\n\t\t\t\t\t\t\t\t\t\tclass: CLASS_BY_TYPE[tok.type],\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn DecorationSet.create(state.doc, decorations);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["CLASS_BY_TYPE","lineCount","text","JsonCodeBlockView","node","pre","gutter","code","count","numbers","n","span","mutation","JsonHighlightExtension","Extension","selection","empty","$from","Plugin","PluginKey","transactions","_oldState","newState","tr","doc","schema","codeBlock","hasCodeBlock","TextSelection","view","event","raw","value","pretty","state","dispatch","from","to","decorations","pos","base","tok","tokenizeJson","Decoration","DecorationSet"],"mappings":"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"}
1
+ {"version":3,"file":"JsonHighlightExtension.js","sources":["../../../../../src/editor/extensions/jsonHighlight/JsonHighlightExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model';\nimport { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state';\nimport type { NodeView } from '@tiptap/pm/view';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\nimport { JsonTokenType, tokenizeJson } from './tokenizeJson';\n\nconst CLASS_BY_TYPE: Record<JsonTokenType, string> = {\n\tkey: 'bik-json-key',\n\tstring: 'bik-json-string',\n\tnumber: 'bik-json-number',\n\tboolean: 'bik-json-boolean',\n\tnull: 'bik-json-null',\n\tpunctuation: 'bik-json-punct',\n};\n\n/**\n * Visual line count of a code block's text (0 → no gutter). Whitespace-only\n * content counts as 0: that's exactly when BikEditor shows the placeholder\n * overlay (`jsonEmpty = !text.trim()`), so the gutter must be empty too —\n * otherwise a blank field shows a stray \"1\" behind the placeholder.\n */\nfunction lineCount(text: string): number {\n\treturn text.trim().length === 0 ? 0 : text.split('\\n').length;\n}\n\n/**\n * Node view for the JSON `codeBlock` that renders the line-number gutter as a\n * `contenteditable=false` sibling of the editable `<code>` — NOT as ProseMirror\n * widget decorations.\n *\n * Why: widget decorations are re-inserted into the content flow on every\n * decoration recompute (i.e. every keystroke). Re-inserting a node next to the\n * caret reset the contenteditable selection to the line start, so typing a JSON\n * key and then its `:` dropped the caret to the start of the line (MAP-7286).\n * A node view lets us update the gutter DOM independently of `contentDOM`, so\n * the caret is never touched — and we only rebuild it when the line count\n * actually changes.\n */\nclass JsonCodeBlockView implements NodeView {\n\tdom: HTMLPreElement;\n\tcontentDOM: HTMLElement;\n\tprivate gutter: HTMLElement;\n\n\tconstructor(node: ProseMirrorNode) {\n\t\tconst pre = document.createElement('pre');\n\t\tconst gutter = document.createElement('div');\n\t\tgutter.className = 'bik-json-gutter';\n\t\tgutter.contentEditable = 'false';\n\t\tconst code = document.createElement('code');\n\t\t// Gutter is absolutely positioned into the reserved left padding, so its\n\t\t// order relative to <code> doesn't affect the code layout.\n\t\tpre.appendChild(gutter);\n\t\tpre.appendChild(code);\n\n\t\tthis.dom = pre;\n\t\tthis.contentDOM = code;\n\t\tthis.gutter = gutter;\n\t\tthis.renderGutter(node);\n\t}\n\n\tprivate renderGutter(node: ProseMirrorNode): void {\n\t\tconst count = lineCount(node.textContent);\n\t\t// Nothing to do while the line count is unchanged — this is the common case\n\t\t// (typing within a line) and skipping it avoids touching the gutter DOM.\n\t\tif (this.gutter.childElementCount === count) {\n\t\t\treturn;\n\t\t}\n\t\t// Reserve only as much left space as the widest line number needs. Floored\n\t\t// at 2 digits so JSON up to 99 lines (virtually all of it) keeps a stable\n\t\t// compact gutter; 100+ / 1000+ lines widen it (and the code's left padding)\n\t\t// a step at a time instead of always paying for 5 digits.\n\t\tconst digits = Math.max(2, String(Math.max(count, 1)).length);\n\t\tconst gutterEm = digits * 0.6 + 1.1;\n\t\tthis.gutter.style.width = `${gutterEm}em`;\n\t\tthis.dom.style.paddingLeft = `${gutterEm + 0.7}em`;\n\t\tconst numbers: HTMLElement[] = [];\n\t\tfor (let n = 1; n <= count; n++) {\n\t\t\tconst span = document.createElement('span');\n\t\t\tspan.className = 'bik-json-lineno';\n\t\t\tspan.textContent = String(n);\n\t\t\tnumbers.push(span);\n\t\t}\n\t\tthis.gutter.replaceChildren(...numbers);\n\t}\n\n\tupdate(node: ProseMirrorNode): boolean {\n\t\tif (node.type.name !== 'codeBlock') {\n\t\t\treturn false;\n\t\t}\n\t\tthis.renderGutter(node);\n\t\treturn true;\n\t}\n\n\t// The gutter is ours to manage — never let ProseMirror parse it as content.\n\tignoreMutation(mutation: MutationRecord | { target: Node }): boolean {\n\t\treturn (\n\t\t\tthis.gutter === mutation.target || this.gutter.contains(mutation.target)\n\t\t);\n\t}\n}\n\n/**\n * Colours JSON tokens inside `codeBlock` nodes and renders a line-number gutter\n * (via {@link JsonCodeBlockView}). A code block stores its whole multi-line body\n * in a single text node, so token offsets map 1:1 onto document positions\n * (`nodeStart + offset`) — no cross-node bookkeeping needed.\n *\n * Purely decorative: the document text is never rewritten, so undo/redo,\n * character count and the cursor all behave exactly as with plain text.\n */\nexport const JsonHighlightExtension = Extension.create({\n\tname: 'jsonHighlight',\n\t// Above CodeBlock (default 100) so our Backspace handler runs first and can\n\t// veto CodeBlock's own \"clearNodes at start\" shortcut (which would lift the\n\t// block to a paragraph).\n\tpriority: 1000,\n\taddKeyboardShortcuts() {\n\t\treturn {\n\t\t\t// In JSON mode the document is a single code block. A Backspace at its very\n\t\t\t// start would lift it to a plain paragraph (killing the highlight, the\n\t\t\t// line-number gutter and the monospace font). There's nothing to delete\n\t\t\t// before the caret there anyway, so swallow it. Mid-text Backspace (and\n\t\t\t// deleting a leading `\\n` from line 2+) still works — those have\n\t\t\t// parentOffset > 0.\n\t\t\tBackspace: () => {\n\t\t\t\tconst { selection } = this.editor.state;\n\t\t\t\tconst { empty, $from } = selection;\n\t\t\t\treturn (\n\t\t\t\t\tempty &&\n\t\t\t\t\t$from.parent.type.name === 'codeBlock' &&\n\t\t\t\t\t$from.parentOffset === 0\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlightGuard'),\n\t\t\t\t// jsonMode invariant: the whole document is ONE codeBlock. Several\n\t\t\t\t// default Backspace paths can lift it to a plain paragraph — and one\n\t\t\t\t// of them, TipTap core's `clearDocument` appendTransaction (fired when\n\t\t\t\t// the whole doc is selected then deleted, e.g. Cmd-A → Backspace),\n\t\t\t\t// runs AFTER our Backspace shortcut, so a keymap veto can't stop it.\n\t\t\t\t// A paragraph has no gutter and no monospace rule, so the line numbers\n\t\t\t\t// and font vanish. Re-wrap the content back into a codeBlock whenever\n\t\t\t\t// something lifts it, restoring the invariant.\n\t\t\t\tappendTransaction(transactions, _oldState, newState) {\n\t\t\t\t\tif (!transactions.some((tr) => tr.docChanged)) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst { doc, schema } = newState;\n\t\t\t\t\tconst codeBlock = schema.nodes['codeBlock'];\n\t\t\t\t\tif (!codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// Common case: already a single codeBlock → nothing to do.\n\t\t\t\t\tif (doc.childCount === 1 && doc.firstChild?.type === codeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// If a codeBlock survives anywhere, leave it alone (don't fight\n\t\t\t\t\t// legitimate multi-node edits that shouldn't happen in jsonMode).\n\t\t\t\t\tlet hasCodeBlock = false;\n\t\t\t\t\tdoc.forEach((node) => {\n\t\t\t\t\t\tif (node.type === codeBlock) {\n\t\t\t\t\t\t\thasCodeBlock = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (hasCodeBlock) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\t// A lift happened: rebuild a single codeBlock from the text\n\t\t\t\t\t// (block boundaries preserved as newlines, matching JSON lines).\n\t\t\t\t\tconst text = doc.textBetween(0, doc.content.size, '\\n');\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\ttr.replaceWith(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\tdoc.content.size,\n\t\t\t\t\t\tcodeBlock.create(null, text ? schema.text(text) : null),\n\t\t\t\t\t);\n\t\t\t\t\ttr.setSelection(TextSelection.create(tr.doc, 1));\n\t\t\t\t\treturn tr;\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('jsonHighlight'),\n\t\t\t\tprops: {\n\t\t\t\t\t// The gutter is a node view, not a widget decoration — see\n\t\t\t\t\t// JsonCodeBlockView for why (MAP-7286).\n\t\t\t\t\tnodeViews: {\n\t\t\t\t\t\tcodeBlock: (node) => new JsonCodeBlockView(node),\n\t\t\t\t\t},\n\t\t\t\t\t// Paste beautify: if the clipboard text is valid JSON, drop in a\n\t\t\t\t\t// pretty-printed version (2-space indent, matching the Beautify\n\t\t\t\t\t// button) instead of the raw blob. Non-JSON pastes fall through to\n\t\t\t\t\t// the default handler untouched.\n\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\tconst raw = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!raw || !raw.trim()) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet value: unknown;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tvalue = JSON.parse(raw);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst pretty = JSON.stringify(value, null, 2);\n\t\t\t\t\t\t// No-op if it was already beautified (avoids a redundant tx).\n\t\t\t\t\t\tif (pretty === raw) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { state, dispatch } = view;\n\t\t\t\t\t\tconst { from, to } = state.selection;\n\t\t\t\t\t\tdispatch(state.tr.insertText(pretty, from, to).scrollIntoView());\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\t// Inline token colours only. Recolouring an inline span does not\n\t\t\t\t\t// disturb the caret (unlike the old gutter widgets).\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst decorations: Decoration[] = [];\n\t\t\t\t\t\tstate.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (node.type.name !== 'codeBlock') return;\n\t\t\t\t\t\t\tconst text = node.textContent;\n\t\t\t\t\t\t\tif (text.length === 0) return;\n\t\t\t\t\t\t\t// +1: step past the code-block node boundary into its text.\n\t\t\t\t\t\t\tconst base = pos + 1;\n\t\t\t\t\t\t\tfor (const tok of tokenizeJson(text)) {\n\t\t\t\t\t\t\t\tdecorations.push(\n\t\t\t\t\t\t\t\t\tDecoration.inline(base + tok.start, base + tok.end, {\n\t\t\t\t\t\t\t\t\t\tclass: CLASS_BY_TYPE[tok.type],\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn DecorationSet.create(state.doc, decorations);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["CLASS_BY_TYPE","lineCount","text","JsonCodeBlockView","node","pre","gutter","code","count","gutterEm","numbers","n","span","mutation","JsonHighlightExtension","Extension","selection","empty","$from","Plugin","PluginKey","transactions","_oldState","newState","tr","doc","schema","codeBlock","hasCodeBlock","TextSelection","view","event","raw","value","pretty","state","dispatch","from","to","decorations","pos","base","tok","tokenizeJson","Decoration","DecorationSet"],"mappings":"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"}
@@ -1,49 +1,49 @@
1
- import { jsx as t, Fragment as x, jsxs as y } from "react/jsx-runtime";
2
- import { forwardRef as A, useState as I, useRef as g, useCallback as k, useImperativeHandle as v, useEffect as C } from "react";
1
+ import { jsx as t, Fragment as p, jsxs as b } from "react/jsx-runtime";
2
+ import { forwardRef as A, useState as I, useRef as x, useCallback as w, useImperativeHandle as v, useEffect as C } from "react";
3
3
  import { DropdownContainer as D, DropdownItem as R, MentionAvatar as U, MentionAvatarFallback as E, MentionLabel as H, MentionPresenceDot as K } from "../editorDropdown.styles.js";
4
4
  const S = A(
5
- ({ items: r, query: u, command: i, renderItem: f, renderDropdown: o, dismiss: w }, M) => {
6
- const [c, a] = I(0), d = g(null), s = g(null), b = k(
5
+ ({ items: r, query: g, command: u, renderItem: i, renderDropdown: a, dismiss: k }, y) => {
6
+ const [l, c] = I(0), f = x(null), s = x(null), M = w(
7
7
  (n) => {
8
8
  s.current = n;
9
9
  },
10
10
  []
11
- ), h = k((n) => {
12
- const e = d.current;
11
+ ), d = w((n) => {
12
+ const e = f.current;
13
13
  if (!e) return;
14
14
  e.children[n]?.scrollIntoView({ block: "nearest" });
15
- }, []), p = (n) => {
16
- r[n] && i(r[n]);
15
+ }, []), h = (n) => {
16
+ r[n] && u(r[n]);
17
17
  };
18
- return v(M, () => ({
19
- onKeyDown: ({ event: n }) => o && s.current ? s.current(n) : r.length ? n.key === "ArrowUp" ? (a((e) => {
20
- const l = (e + r.length - 1) % r.length;
21
- return h(l), l;
22
- }), !0) : n.key === "ArrowDown" ? (a((e) => {
23
- const l = (e + 1) % r.length;
24
- return h(l), l;
25
- }), !0) : n.key === "Enter" ? (p(c), !0) : !1 : !1
26
- })), C(() => a(0), [r]), !r.length && (!o || u) ? null : o ? /* @__PURE__ */ t(x, { children: o({
18
+ return v(y, () => ({
19
+ onKeyDown: ({ event: n }) => a && s.current ? s.current(n) : r.length ? n.key === "ArrowUp" ? (c((e) => {
20
+ const o = (e + r.length - 1) % r.length;
21
+ return d(o), o;
22
+ }), !0) : n.key === "ArrowDown" ? (c((e) => {
23
+ const o = (e + 1) % r.length;
24
+ return d(o), o;
25
+ }), !0) : n.key === "Enter" ? (h(l), !0) : !1 : !1
26
+ })), C(() => c(0), [r]), r.length ? a ? /* @__PURE__ */ t(p, { children: a({
27
27
  items: r,
28
- query: u,
29
- activeIndex: c,
30
- onSelect: (n) => i(n),
31
- registerKeyHandler: b,
32
- onClose: w
33
- }) }) : /* @__PURE__ */ t(D, { ref: d, children: r.map((n, e) => /* @__PURE__ */ t(
28
+ query: g,
29
+ activeIndex: l,
30
+ onSelect: (n) => u(n),
31
+ registerKeyHandler: M,
32
+ onClose: k
33
+ }) }) : /* @__PURE__ */ t(D, { ref: f, children: r.map((n, e) => /* @__PURE__ */ t(
34
34
  R,
35
35
  {
36
- $isActive: e === c,
37
- onMouseEnter: () => a(e),
38
- onClick: () => p(e),
39
- children: f ? f(n, e === c) : /* @__PURE__ */ y(x, { children: [
36
+ $isActive: e === l,
37
+ onMouseEnter: () => c(e),
38
+ onClick: () => h(e),
39
+ children: i ? i(n, e === l) : /* @__PURE__ */ b(p, { children: [
40
40
  n.avatarUrl ? /* @__PURE__ */ t(U, { src: n.avatarUrl, alt: "" }) : /* @__PURE__ */ t(E, { children: n.label.charAt(0).toUpperCase() }),
41
41
  /* @__PURE__ */ t(H, { children: n.label }),
42
42
  n.isOnline !== void 0 && /* @__PURE__ */ t(K, { $online: n.isOnline })
43
43
  ] })
44
44
  },
45
45
  n.id
46
- )) });
46
+ )) }) : null;
47
47
  }
48
48
  );
49
49
  S.displayName = "MentionDropdown";
@@ -1 +1 @@
1
- {"version":3,"file":"MentionDropdown.js","sources":["../../../../../src/editor/extensions/mention/MentionDropdown.tsx"],"sourcesContent":["import React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tDropdownContainer,\n\tDropdownItem,\n\tMentionAvatar,\n\tMentionAvatarFallback,\n\tMentionLabel,\n\tMentionPresenceDot,\n} from '../editorDropdown.styles';\n\ninterface Props {\n\titems: MentionItem[];\n\tquery: string;\n\tcommand: (item: MentionItem) => void;\n\t/** Custom per-row renderer. Receives the item and whether it is the active row. */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Full custom dropdown renderer. Takes priority over renderItem.\n\t * The editor passes activeIndex and onSelect — you handle all the visual rendering.\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/** Close the menu without selecting (strips the typed trigger). Injected by the extension. */\n\tdismiss?: () => void;\n}\n\nexport const MentionDropdown = forwardRef<any, Props>(\n\t({ items, query, command, renderItem, renderDropdown, dismiss }, ref) => {\n\t\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\t// A custom dropdown (renderDropdown) can claim keyboard nav for itself.\n\t\tconst customKeyHandlerRef = useRef<\n\t\t\t((event: KeyboardEvent) => boolean) | null\n\t\t>(null);\n\n\t\tconst registerKeyHandler = useCallback(\n\t\t\t(handler: ((event: KeyboardEvent) => boolean) | null) => {\n\t\t\t\tcustomKeyHandlerRef.current = handler;\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst scrollToIndex = useCallback((index: number) => {\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!container) return;\n\t\t\tconst item = container.children[index] as HTMLElement | undefined;\n\t\t\titem?.scrollIntoView({ block: 'nearest' });\n\t\t}, []);\n\n\t\tconst select = (i: number) => {\n\t\t\tif (items[i]) command(items[i]);\n\t\t};\n\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tonKeyDown: ({ event }: { event: KeyboardEvent }) => {\n\t\t\t\t// A custom dropdown that registered a handler owns navigation.\n\t\t\t\tif (renderDropdown && customKeyHandlerRef.current) {\n\t\t\t\t\treturn customKeyHandlerRef.current(event);\n\t\t\t\t}\n\t\t\t\tif (!items.length) return false;\n\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + items.length - 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tselect(selectedIndex);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t}));\n\n\t\tuseEffect(() => setSelectedIndex(0), [items]);\n\n\t\t// A custom dropdown owns its own empty state — it can have content even\n\t\t// with zero mention items (e.g. the agent-builder's variables-only mode) —\n\t\t// but only while the query is empty. Once a typed query filters to zero,\n\t\t// bail (unmounting the custom dropdown unregisters its key handler, so\n\t\t// Enter / arrows reach the editor again). Mirrors MentionExtension's\n\t\t// popup.hide() rule.\n\t\tif (!items.length && (!renderDropdown || query)) return null;\n\n\t\t// Full custom dropdown — editor still manages keyboard nav via selectedIndex\n\t\tif (renderDropdown) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{renderDropdown({\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\tactiveIndex: selectedIndex,\n\t\t\t\t\t\tonSelect: (item) => command(item),\n\t\t\t\t\t\tregisterKeyHandler,\n\t\t\t\t\t\tonClose: dismiss,\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<DropdownContainer ref={containerRef}>\n\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t<DropdownItem\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t$isActive={i === selectedIndex}\n\t\t\t\t\t\tonMouseEnter={() => setSelectedIndex(i)}\n\t\t\t\t\t\tonClick={() => select(i)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\trenderItem(item, i === selectedIndex)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{item.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<MentionAvatar src={item.avatarUrl} alt=\"\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<MentionAvatarFallback>\n\t\t\t\t\t\t\t\t\t\t{item.label.charAt(0).toUpperCase()}\n\t\t\t\t\t\t\t\t\t</MentionAvatarFallback>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<MentionLabel>{item.label}</MentionLabel>\n\t\t\t\t\t\t\t\t{item.isOnline !== undefined && (\n\t\t\t\t\t\t\t\t\t<MentionPresenceDot $online={item.isOnline} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</DropdownItem>\n\t\t\t\t))}\n\t\t\t</DropdownContainer>\n\t\t);\n\t},\n);\nMentionDropdown.displayName = 'MentionDropdown';\n"],"names":["MentionDropdown","forwardRef","items","query","command","renderItem","renderDropdown","dismiss","ref","selectedIndex","setSelectedIndex","useState","containerRef","useRef","customKeyHandlerRef","registerKeyHandler","useCallback","handler","scrollToIndex","index","container","select","i","useImperativeHandle","event","prev","next","useEffect","item","jsx","DropdownContainer","DropdownItem","jsxs","Fragment","MentionAvatar","MentionAvatarFallback","MentionLabel","MentionPresenceDot"],"mappings":";;;AAoCO,MAAMA,IAAkBC;AAAA,EAC9B,CAAC,EAAE,OAAAC,GAAO,OAAAC,GAAO,SAAAC,GAAS,YAAAC,GAAY,gBAAAC,GAAgB,SAAAC,EAAA,GAAWC,MAAQ;AACxE,UAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAS,CAAC,GAC9CC,IAAeC,EAAuB,IAAI,GAE1CC,IAAsBD,EAE1B,IAAI,GAEAE,IAAqBC;AAAA,MAC1B,CAACC,MAAwD;AACxD,QAAAH,EAAoB,UAAUG;AAAA,MAC/B;AAAA,MACA,CAAA;AAAA,IAAC,GAGIC,IAAgBF,EAAY,CAACG,MAAkB;AACpD,YAAMC,IAAYR,EAAa;AAC/B,UAAI,CAACQ,EAAW;AAEhB,MADaA,EAAU,SAASD,CAAK,GAC/B,eAAe,EAAE,OAAO,UAAA,CAAW;AAAA,IAC1C,GAAG,CAAA,CAAE,GAECE,IAAS,CAACC,MAAc;AAC7B,MAAIpB,EAAMoB,CAAC,KAAGlB,EAAQF,EAAMoB,CAAC,CAAC;AAAA,IAC/B;AAyCA,WAvCAC,EAAoBf,GAAK,OAAO;AAAA,MAC/B,WAAW,CAAC,EAAE,OAAAgB,QAETlB,KAAkBQ,EAAoB,UAClCA,EAAoB,QAAQU,CAAK,IAEpCtB,EAAM,SACPsB,EAAM,QAAQ,aACjBd,EAAiB,CAACe,MAAS;AAC1B,cAAMC,KAAQD,IAAOvB,EAAM,SAAS,KAAKA,EAAM;AAC/C,eAAAgB,EAAcQ,CAAI,GACXA;AAAA,MACR,CAAC,GACM,MAEJF,EAAM,QAAQ,eACjBd,EAAiB,CAACe,MAAS;AAC1B,cAAMC,KAAQD,IAAO,KAAKvB,EAAM;AAChC,eAAAgB,EAAcQ,CAAI,GACXA;AAAA,MACR,CAAC,GACM,MAEJF,EAAM,QAAQ,WACjBH,EAAOZ,CAAa,GACb,MAED,KArBmB;AAAA,IAsB3B,EACC,GAEFkB,EAAU,MAAMjB,EAAiB,CAAC,GAAG,CAACR,CAAK,CAAC,GAQxC,CAACA,EAAM,WAAW,CAACI,KAAkBH,KAAe,OAGpDG,2BAGA,UAAAA,EAAe;AAAA,MACf,OAAAJ;AAAA,MACA,OAAAC;AAAA,MACA,aAAaM;AAAA,MACb,UAAU,CAACmB,MAASxB,EAAQwB,CAAI;AAAA,MAChC,oBAAAb;AAAA,MACA,SAASR;AAAA,IAAA,CACT,GACF,IAKD,gBAAAsB,EAACC,KAAkB,KAAKlB,GACtB,YAAM,IAAI,CAACgB,GAAMN,MACjB,gBAAAO;AAAA,MAACE;AAAA,MAAA;AAAA,QAEA,WAAWT,MAAMb;AAAA,QACjB,cAAc,MAAMC,EAAiBY,CAAC;AAAA,QACtC,SAAS,MAAMD,EAAOC,CAAC;AAAA,QAEtB,cACAjB,EAAWuB,GAAMN,MAAMb,CAAa,IAEpC,gBAAAuB,EAAAC,GAAA,EACE,UAAA;AAAA,UAAAL,EAAK,YACL,gBAAAC,EAACK,GAAA,EAAc,KAAKN,EAAK,WAAW,KAAI,GAAA,CAAG,IAE3C,gBAAAC,EAACM,KACC,UAAAP,EAAK,MAAM,OAAO,CAAC,EAAE,eACvB;AAAA,UAED,gBAAAC,EAACO,GAAA,EAAc,UAAAR,EAAK,MAAA,CAAM;AAAA,UACzBA,EAAK,aAAa,4BACjBS,GAAA,EAAmB,SAAST,EAAK,SAAA,CAAU;AAAA,QAAA,EAAA,CAE9C;AAAA,MAAA;AAAA,MApBIA,EAAK;AAAA,IAAA,CAuBX,GACF;AAAA,EAEF;AACD;AACA5B,EAAgB,cAAc;"}
1
+ {"version":3,"file":"MentionDropdown.js","sources":["../../../../../src/editor/extensions/mention/MentionDropdown.tsx"],"sourcesContent":["import React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tDropdownContainer,\n\tDropdownItem,\n\tMentionAvatar,\n\tMentionAvatarFallback,\n\tMentionLabel,\n\tMentionPresenceDot,\n} from '../editorDropdown.styles';\n\ninterface Props {\n\titems: MentionItem[];\n\tquery: string;\n\tcommand: (item: MentionItem) => void;\n\t/** Custom per-row renderer. Receives the item and whether it is the active row. */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Full custom dropdown renderer. Takes priority over renderItem.\n\t * The editor passes activeIndex and onSelect — you handle all the visual rendering.\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/** Close the menu without selecting (strips the typed trigger). Injected by the extension. */\n\tdismiss?: () => void;\n}\n\nexport const MentionDropdown = forwardRef<any, Props>(\n\t({ items, query, command, renderItem, renderDropdown, dismiss }, ref) => {\n\t\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\t// A custom dropdown (renderDropdown) can claim keyboard nav for itself.\n\t\tconst customKeyHandlerRef = useRef<\n\t\t\t((event: KeyboardEvent) => boolean) | null\n\t\t>(null);\n\n\t\tconst registerKeyHandler = useCallback(\n\t\t\t(handler: ((event: KeyboardEvent) => boolean) | null) => {\n\t\t\t\tcustomKeyHandlerRef.current = handler;\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst scrollToIndex = useCallback((index: number) => {\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!container) return;\n\t\t\tconst item = container.children[index] as HTMLElement | undefined;\n\t\t\titem?.scrollIntoView({ block: 'nearest' });\n\t\t}, []);\n\n\t\tconst select = (i: number) => {\n\t\t\tif (items[i]) command(items[i]);\n\t\t};\n\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tonKeyDown: ({ event }: { event: KeyboardEvent }) => {\n\t\t\t\t// A custom dropdown that registered a handler owns navigation.\n\t\t\t\tif (renderDropdown && customKeyHandlerRef.current) {\n\t\t\t\t\treturn customKeyHandlerRef.current(event);\n\t\t\t\t}\n\t\t\t\tif (!items.length) return false;\n\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + items.length - 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tselect(selectedIndex);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t}));\n\n\t\tuseEffect(() => setSelectedIndex(0), [items]);\n\n\t\tif (!items.length) return null;\n\n\t\t// Full custom dropdown — editor still manages keyboard nav via selectedIndex\n\t\tif (renderDropdown) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{renderDropdown({\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\tactiveIndex: selectedIndex,\n\t\t\t\t\t\tonSelect: (item) => command(item),\n\t\t\t\t\t\tregisterKeyHandler,\n\t\t\t\t\t\tonClose: dismiss,\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<DropdownContainer ref={containerRef}>\n\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t<DropdownItem\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t$isActive={i === selectedIndex}\n\t\t\t\t\t\tonMouseEnter={() => setSelectedIndex(i)}\n\t\t\t\t\t\tonClick={() => select(i)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\trenderItem(item, i === selectedIndex)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{item.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<MentionAvatar src={item.avatarUrl} alt=\"\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<MentionAvatarFallback>\n\t\t\t\t\t\t\t\t\t\t{item.label.charAt(0).toUpperCase()}\n\t\t\t\t\t\t\t\t\t</MentionAvatarFallback>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<MentionLabel>{item.label}</MentionLabel>\n\t\t\t\t\t\t\t\t{item.isOnline !== undefined && (\n\t\t\t\t\t\t\t\t\t<MentionPresenceDot $online={item.isOnline} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</DropdownItem>\n\t\t\t\t))}\n\t\t\t</DropdownContainer>\n\t\t);\n\t},\n);\nMentionDropdown.displayName = 'MentionDropdown';\n"],"names":["MentionDropdown","forwardRef","items","query","command","renderItem","renderDropdown","dismiss","ref","selectedIndex","setSelectedIndex","useState","containerRef","useRef","customKeyHandlerRef","registerKeyHandler","useCallback","handler","scrollToIndex","index","container","select","i","useImperativeHandle","event","prev","next","useEffect","item","jsx","DropdownContainer","DropdownItem","jsxs","Fragment","MentionAvatar","MentionAvatarFallback","MentionLabel","MentionPresenceDot"],"mappings":";;;AAoCO,MAAMA,IAAkBC;AAAA,EAC9B,CAAC,EAAE,OAAAC,GAAO,OAAAC,GAAO,SAAAC,GAAS,YAAAC,GAAY,gBAAAC,GAAgB,SAAAC,EAAA,GAAWC,MAAQ;AACxE,UAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAS,CAAC,GAC9CC,IAAeC,EAAuB,IAAI,GAE1CC,IAAsBD,EAE1B,IAAI,GAEAE,IAAqBC;AAAA,MAC1B,CAACC,MAAwD;AACxD,QAAAH,EAAoB,UAAUG;AAAA,MAC/B;AAAA,MACA,CAAA;AAAA,IAAC,GAGIC,IAAgBF,EAAY,CAACG,MAAkB;AACpD,YAAMC,IAAYR,EAAa;AAC/B,UAAI,CAACQ,EAAW;AAEhB,MADaA,EAAU,SAASD,CAAK,GAC/B,eAAe,EAAE,OAAO,UAAA,CAAW;AAAA,IAC1C,GAAG,CAAA,CAAE,GAECE,IAAS,CAACC,MAAc;AAC7B,MAAIpB,EAAMoB,CAAC,KAAGlB,EAAQF,EAAMoB,CAAC,CAAC;AAAA,IAC/B;AAmCA,WAjCAC,EAAoBf,GAAK,OAAO;AAAA,MAC/B,WAAW,CAAC,EAAE,OAAAgB,QAETlB,KAAkBQ,EAAoB,UAClCA,EAAoB,QAAQU,CAAK,IAEpCtB,EAAM,SACPsB,EAAM,QAAQ,aACjBd,EAAiB,CAACe,MAAS;AAC1B,cAAMC,KAAQD,IAAOvB,EAAM,SAAS,KAAKA,EAAM;AAC/C,eAAAgB,EAAcQ,CAAI,GACXA;AAAA,MACR,CAAC,GACM,MAEJF,EAAM,QAAQ,eACjBd,EAAiB,CAACe,MAAS;AAC1B,cAAMC,KAAQD,IAAO,KAAKvB,EAAM;AAChC,eAAAgB,EAAcQ,CAAI,GACXA;AAAA,MACR,CAAC,GACM,MAEJF,EAAM,QAAQ,WACjBH,EAAOZ,CAAa,GACb,MAED,KArBmB;AAAA,IAsB3B,EACC,GAEFkB,EAAU,MAAMjB,EAAiB,CAAC,GAAG,CAACR,CAAK,CAAC,GAEvCA,EAAM,SAGPI,2BAGA,UAAAA,EAAe;AAAA,MACf,OAAAJ;AAAA,MACA,OAAAC;AAAA,MACA,aAAaM;AAAA,MACb,UAAU,CAACmB,MAASxB,EAAQwB,CAAI;AAAA,MAChC,oBAAAb;AAAA,MACA,SAASR;AAAA,IAAA,CACT,GACF,IAKD,gBAAAsB,EAACC,KAAkB,KAAKlB,GACtB,YAAM,IAAI,CAACgB,GAAMN,MACjB,gBAAAO;AAAA,MAACE;AAAA,MAAA;AAAA,QAEA,WAAWT,MAAMb;AAAA,QACjB,cAAc,MAAMC,EAAiBY,CAAC;AAAA,QACtC,SAAS,MAAMD,EAAOC,CAAC;AAAA,QAEtB,cACAjB,EAAWuB,GAAMN,MAAMb,CAAa,IAEpC,gBAAAuB,EAAAC,GAAA,EACE,UAAA;AAAA,UAAAL,EAAK,YACL,gBAAAC,EAACK,GAAA,EAAc,KAAKN,EAAK,WAAW,KAAI,GAAA,CAAG,IAE3C,gBAAAC,EAACM,KACC,UAAAP,EAAK,MAAM,OAAO,CAAC,EAAE,eACvB;AAAA,UAED,gBAAAC,EAACO,GAAA,EAAc,UAAAR,EAAK,MAAA,CAAM;AAAA,UACzBA,EAAK,aAAa,4BACjBS,GAAA,EAAmB,SAAST,EAAK,SAAA,CAAU;AAAA,QAAA,EAAA,CAE9C;AAAA,MAAA;AAAA,MApBIA,EAAK;AAAA,IAAA,CAuBX,GACF,IA9CyB;AAAA,EAgD3B;AACD;AACA5B,EAAgB,cAAc;"}
@@ -2,10 +2,10 @@ import { mergeAttributes as f } from "../../../node_modules/@tiptap/core/dist/in
2
2
  import k from "@tiptap/extension-mention";
3
3
  import { ReactNodeViewRenderer as b, ReactRenderer as w } from "@tiptap/react";
4
4
  import { createSuggestionPopup as h } from "../suggestionPopup.js";
5
- import { buildMentionChipNodeView as M } from "./MentionChipNodeView.js";
6
- import { MentionDropdown as p } from "./MentionDropdown.js";
7
- function T(a, r) {
8
- const { renderItem: d, renderDropdown: u, removeTriggerOnDismiss: c } = a;
5
+ import { buildMentionChipNodeView as p } from "./MentionChipNodeView.js";
6
+ import { MentionDropdown as M } from "./MentionDropdown.js";
7
+ function T(u, r) {
8
+ const { renderItem: d, renderDropdown: a, removeTriggerOnDismiss: c } = u;
9
9
  return () => {
10
10
  let i, o, e, t = null;
11
11
  const s = () => {
@@ -16,8 +16,8 @@ function T(a, r) {
16
16
  };
17
17
  return {
18
18
  onStart: (n) => {
19
- e = n, r.picked = !1, i = new w(p, {
20
- props: { ...n, renderItem: d, renderDropdown: u, dismiss: s },
19
+ e = n, r.picked = !1, i = new w(M, {
20
+ props: { ...n, renderItem: d, renderDropdown: a, dismiss: s },
21
21
  editor: n.editor
22
22
  }), o = h(i.element, n.clientRect), t = (l) => {
23
23
  const m = l.target;
@@ -28,9 +28,9 @@ function T(a, r) {
28
28
  if (e = n, i.updateProps({
29
29
  ...n,
30
30
  renderItem: d,
31
- renderDropdown: u,
31
+ renderDropdown: a,
32
32
  dismiss: s
33
- }), !n.items?.length && (!u || n.query)) {
33
+ }), !n.items?.length) {
34
34
  o.hide();
35
35
  return;
36
36
  }
@@ -48,10 +48,10 @@ function T(a, r) {
48
48
  };
49
49
  };
50
50
  }
51
- function g(a, r, d, u, c, i) {
51
+ function g(u, r, d, a, c, i) {
52
52
  const o = { picked: !1 };
53
53
  return k.extend({
54
- name: a,
54
+ name: u,
55
55
  addAttributes() {
56
56
  return {
57
57
  ...this.parent?.(),
@@ -73,7 +73,7 @@ function g(a, r, d, u, c, i) {
73
73
  ...i.renderChipIcon ? {
74
74
  addNodeView() {
75
75
  return b(
76
- M({
76
+ p({
77
77
  cssClass: r,
78
78
  char: d,
79
79
  renderChipIcon: i.renderChipIcon
@@ -96,16 +96,12 @@ function g(a, r, d, u, c, i) {
96
96
  suggestion: {
97
97
  char: d,
98
98
  allowSpaces: !0,
99
- // Chips are always followed by a `&nbsp;` (see MentionEditor's inserts),
100
- // so U+00A0 must count as a valid prefix or an `@` typed / injected
101
- // right after a chip never activates the suggestion (default: [' ']).
102
- allowedPrefixes: [" ", " "],
103
- items: ({ query: e }) => u.current.filter(
99
+ items: ({ query: e }) => a.current.filter(
104
100
  (t) => t.label.toLowerCase().includes(e.toLowerCase())
105
101
  ),
106
102
  command: ({ editor: e, range: t, props: s }) => {
107
103
  o.picked = !0, e.chain().focus().deleteRange(t).insertContent({
108
- type: a,
104
+ type: u,
109
105
  attrs: {
110
106
  id: s.id,
111
107
  label: s.label,
@@ -118,24 +114,24 @@ function g(a, r, d, u, c, i) {
118
114
  }
119
115
  });
120
116
  }
121
- function H(a, r, d, u, c, i) {
117
+ function H(u, r, d, a, c, i) {
122
118
  return g(
123
119
  "mentionAgent",
124
120
  "bik-mention bik-mention--agent",
125
121
  "@",
126
- a,
122
+ u,
127
123
  r,
128
- { renderItem: d, renderDropdown: u, removeTriggerOnDismiss: c, renderChipIcon: i }
124
+ { renderItem: d, renderDropdown: a, removeTriggerOnDismiss: c, renderChipIcon: i }
129
125
  );
130
126
  }
131
- function S(a, r, d, u, c) {
127
+ function S(u, r, d, a, c) {
132
128
  return g(
133
129
  "mentionTeam",
134
130
  "bik-mention bik-mention--team",
135
131
  "#",
136
- a,
132
+ u,
137
133
  r,
138
- { renderItem: d, renderDropdown: u, removeTriggerOnDismiss: c }
134
+ { renderItem: d, renderDropdown: a, removeTriggerOnDismiss: c }
139
135
  );
140
136
  }
141
137
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"MentionExtension.js","sources":["../../../../../src/editor/extensions/mention/MentionExtension.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport Mention from '@tiptap/extension-mention';\nimport { ReactNodeViewRenderer, ReactRenderer } from '@tiptap/react';\nimport type { ReactNode } from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { buildMentionChipNodeView } from './MentionChipNodeView';\nimport { MentionDropdown } from './MentionDropdown';\n\ninterface MentionBuildOptions {\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\t/** Remove the typed trigger char + query if the menu closes without a selection. */\n\tremoveTriggerOnDismiss?: boolean;\n\t/**\n\t * Leading glyph rendered inside the chip (e.g. a tool's source icon). Supplying\n\t * it switches the chip to a React node view; omit to keep the plain chip.\n\t */\n\trenderChipIcon?: (source: string | null, kind: string | null) => ReactNode;\n}\n\nfunction buildRender(\n\toptions: MentionBuildOptions,\n\tpickedRef: { picked: boolean },\n) {\n\tconst { renderItem, renderDropdown, removeTriggerOnDismiss } = options;\n\treturn () => {\n\t\tlet component: ReactRenderer;\n\t\tlet popup: SuggestionPopup;\n\t\tlet latestProps: any;\n\t\t// Closes the menu when the user clicks anywhere outside it. The `@` popup\n\t\t// lives on document.body (not inside the editor), so nothing dismisses it on\n\t\t// an outside click otherwise — only Escape / moving the cursor did.\n\t\tlet onDocMouseDown: ((event: MouseEvent) => void) | null = null;\n\n\t\t// Close the menu without a selection: drop the typed \"@query\" so no orphan\n\t\t// trigger is left, and mark as picked so onExit doesn't delete it twice.\n\t\tconst dismiss = () => {\n\t\t\tpickedRef.picked = true;\n\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t}\n\t\t};\n\n\t\treturn {\n\t\t\tonStart: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tpickedRef.picked = false;\n\t\t\t\tcomponent = new ReactRenderer(MentionDropdown, {\n\t\t\t\t\tprops: { ...props, renderItem, renderDropdown, dismiss },\n\t\t\t\t\teditor: props.editor,\n\t\t\t\t});\n\t\t\t\tpopup = createSuggestionPopup(component.element, props.clientRect);\n\t\t\t\tonDocMouseDown = (event: MouseEvent) => {\n\t\t\t\t\tconst target = event.target as Node | null;\n\t\t\t\t\tif (!target) return;\n\t\t\t\t\t// Inside the picker → keep open (row clicks fire on `click`).\n\t\t\t\t\tif (popup.element.contains(target)) return;\n\t\t\t\t\t// Inside the editor → the suggestion plugin already closes it.\n\t\t\t\t\tconst editorDom = latestProps?.editor?.view?.dom as\n\t\t\t\t\t\t| HTMLElement\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (editorDom?.contains(target)) return;\n\t\t\t\t\t// Anywhere else → drop the typed \"@query\" (no refocus — clicking\n\t\t\t\t\t// away shouldn't yank focus back) and close.\n\t\t\t\t\tpickedRef.picked = true;\n\t\t\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\t\t\tlatestProps.editor.chain().deleteRange(latestProps.range).run();\n\t\t\t\t\t}\n\t\t\t\t\tpopup.hide();\n\t\t\t\t};\n\t\t\t\tdocument.addEventListener('mousedown', onDocMouseDown);\n\t\t\t},\n\t\t\tonUpdate: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tcomponent.updateProps({\n\t\t\t\t\t...props,\n\t\t\t\t\trenderItem,\n\t\t\t\t\trenderDropdown,\n\t\t\t\t\tdismiss,\n\t\t\t\t});\n\t\t\t\t// Empty result list closes the dropdown — EXCEPT a custom dropdown\n\t\t\t\t// (renderDropdown) with an empty QUERY: it may have content of its\n\t\t\t\t// own with zero items (the agent-builder's variables-only mode).\n\t\t\t\t// Once the user has typed a query that matches nothing, hide — the\n\t\t\t\t// picker must not float over (and steal keys from) ordinary typing.\n\t\t\t\tif (!props.items?.length && (!renderDropdown || props.query)) {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpopup.show();\n\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t},\n\t\t\tonKeyDown: (props: any) => {\n\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t},\n\t\t\tonExit: () => {\n\t\t\t\tif (onDocMouseDown) {\n\t\t\t\t\tdocument.removeEventListener('mousedown', onDocMouseDown);\n\t\t\t\t\tonDocMouseDown = null;\n\t\t\t\t}\n\t\t\t\tpopup.destroy();\n\t\t\t\tcomponent.destroy();\n\t\t\t\t// Nothing was picked → strip the orphan \"@query\" the user typed.\n\t\t\t\tif (\n\t\t\t\t\tremoveTriggerOnDismiss &&\n\t\t\t\t\t!pickedRef.picked &&\n\t\t\t\t\tlatestProps?.editor &&\n\t\t\t\t\tlatestProps?.range\n\t\t\t\t) {\n\t\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (!editor.isDestroyed) {\n\t\t\t\t\t\t\teditor.chain().deleteRange(range).run();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 0);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t};\n}\n\n/**\n * Builds a TipTap Mention extension.\n *\n * Each inserted node carries an optional `kind` attribute. When set, the chip is\n * rendered WITHOUT the trigger char (the `label` already encodes the full text)\n * and a `data-kind` attribute is emitted so CSS can colour it per kind. When\n * `kind` is null the legacy `${char}${label}` chip is rendered (back-compatible).\n */\nfunction buildMentionExtension(\n\tname: 'mentionAgent' | 'mentionTeam',\n\tcssClass: string,\n\tchar: '@' | '#',\n\titemsRef: { current: MentionItem[] },\n\tonSelect: ((item: MentionItem, char: '@' | '#') => void) | undefined,\n\toptions: MentionBuildOptions,\n) {\n\tconst pickedRef = { picked: false };\n\n\treturn Mention.extend({\n\t\tname,\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\t...this.parent?.(),\n\t\t\t\tkind: {\n\t\t\t\t\tdefault: null,\n\t\t\t\t\tparseHTML: (el: HTMLElement) => el.getAttribute('data-kind'),\n\t\t\t\t\trenderHTML: (attrs: Record<string, unknown>) =>\n\t\t\t\t\t\tattrs['kind'] ? { 'data-kind': String(attrs['kind']) } : {},\n\t\t\t\t},\n\t\t\t\t// Tool source bucket (manifest / shopify / …); drives the chip icon.\n\t\t\t\tsource: {\n\t\t\t\t\tdefault: null,\n\t\t\t\t\tparseHTML: (el: HTMLElement) => el.getAttribute('data-source'),\n\t\t\t\t\trenderHTML: (attrs: Record<string, unknown>) =>\n\t\t\t\t\t\tattrs['source'] ? { 'data-source': String(attrs['source']) } : {},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t// A React chip (with the leading source icon) only when the consumer asks for\n\t\t// it — otherwise the plain renderHTML chip is kept (unchanged for CRM etc.).\n\t\t...(options.renderChipIcon\n\t\t\t? {\n\t\t\t\t\taddNodeView() {\n\t\t\t\t\t\treturn ReactNodeViewRenderer(\n\t\t\t\t\t\t\tbuildMentionChipNodeView({\n\t\t\t\t\t\t\t\tcssClass,\n\t\t\t\t\t\t\t\tchar,\n\t\t\t\t\t\t\t\trenderChipIcon: options.renderChipIcon,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t }\n\t\t\t: {}),\n\t}).configure({\n\t\tHTMLAttributes: { class: cssClass },\n\t\trenderText: ({ options: opt, node }: any) =>\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options: opt, node }: any) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(\n\t\t\t\topt.HTMLAttributes,\n\t\t\t\tnode.attrs['kind'] ? { 'data-kind': String(node.attrs['kind']) } : {},\n\t\t\t\tnode.attrs['source']\n\t\t\t\t\t? { 'data-source': String(node.attrs['source']) }\n\t\t\t\t\t: {},\n\t\t\t),\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar,\n\t\t\tallowSpaces: true,\n\t\t\t// Chips are always followed by a `&nbsp;` (see MentionEditor's inserts),\n\t\t\t// so U+00A0 must count as a valid prefix or an `@` typed / injected\n\t\t\t// right after a chip never activates the suggestion (default: [' ']).\n\t\t\tallowedPrefixes: [' ', '\\u00a0'],\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\titemsRef.current.filter((a) =>\n\t\t\t\t\ta.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\tpickedRef.picked = true;\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: name,\n\t\t\t\t\t\tattrs: {\n\t\t\t\t\t\t\tid: props.id,\n\t\t\t\t\t\t\tlabel: props.label,\n\t\t\t\t\t\t\tkind: props.meta?.kind ?? null,\n\t\t\t\t\t\t\tsource: props.meta?.source ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, char);\n\t\t\t},\n\t\t\trender: buildRender(options, pickedRef),\n\t\t},\n\t});\n}\n\nexport function buildAgentMentionExtension(\n\tagentsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n\trenderChipIcon?: (source: string | null, kind: string | null) => ReactNode,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionAgent',\n\t\t'bik-mention bik-mention--agent',\n\t\t'@',\n\t\tagentsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss, renderChipIcon },\n\t);\n}\n\nexport function buildTeamMentionExtension(\n\tteamsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionTeam',\n\t\t'bik-mention bik-mention--team',\n\t\t'#',\n\t\tteamsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss },\n\t);\n}\n"],"names":["buildRender","options","pickedRef","renderItem","renderDropdown","removeTriggerOnDismiss","component","popup","latestProps","onDocMouseDown","dismiss","editor","range","props","ReactRenderer","MentionDropdown","createSuggestionPopup","event","target","buildMentionExtension","name","cssClass","char","itemsRef","onSelect","Mention","el","attrs","ReactNodeViewRenderer","buildMentionChipNodeView","opt","node","mergeAttributes","query","a","buildAgentMentionExtension","agentsRef","renderChipIcon","buildTeamMentionExtension","teamsRef"],"mappings":"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"}
1
+ {"version":3,"file":"MentionExtension.js","sources":["../../../../../src/editor/extensions/mention/MentionExtension.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport Mention from '@tiptap/extension-mention';\nimport { ReactNodeViewRenderer, ReactRenderer } from '@tiptap/react';\nimport type { ReactNode } from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tcreateSuggestionPopup,\n\ttype SuggestionPopup,\n} from '../suggestionPopup';\nimport { buildMentionChipNodeView } from './MentionChipNodeView';\nimport { MentionDropdown } from './MentionDropdown';\n\ninterface MentionBuildOptions {\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\t/** Remove the typed trigger char + query if the menu closes without a selection. */\n\tremoveTriggerOnDismiss?: boolean;\n\t/**\n\t * Leading glyph rendered inside the chip (e.g. a tool's source icon). Supplying\n\t * it switches the chip to a React node view; omit to keep the plain chip.\n\t */\n\trenderChipIcon?: (source: string | null, kind: string | null) => ReactNode;\n}\n\nfunction buildRender(\n\toptions: MentionBuildOptions,\n\tpickedRef: { picked: boolean },\n) {\n\tconst { renderItem, renderDropdown, removeTriggerOnDismiss } = options;\n\treturn () => {\n\t\tlet component: ReactRenderer;\n\t\tlet popup: SuggestionPopup;\n\t\tlet latestProps: any;\n\t\t// Closes the menu when the user clicks anywhere outside it. The `@` popup\n\t\t// lives on document.body (not inside the editor), so nothing dismisses it on\n\t\t// an outside click otherwise — only Escape / moving the cursor did.\n\t\tlet onDocMouseDown: ((event: MouseEvent) => void) | null = null;\n\n\t\t// Close the menu without a selection: drop the typed \"@query\" so no orphan\n\t\t// trigger is left, and mark as picked so onExit doesn't delete it twice.\n\t\tconst dismiss = () => {\n\t\t\tpickedRef.picked = true;\n\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t}\n\t\t};\n\n\t\treturn {\n\t\t\tonStart: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tpickedRef.picked = false;\n\t\t\t\tcomponent = new ReactRenderer(MentionDropdown, {\n\t\t\t\t\tprops: { ...props, renderItem, renderDropdown, dismiss },\n\t\t\t\t\teditor: props.editor,\n\t\t\t\t});\n\t\t\t\tpopup = createSuggestionPopup(component.element, props.clientRect);\n\t\t\t\tonDocMouseDown = (event: MouseEvent) => {\n\t\t\t\t\tconst target = event.target as Node | null;\n\t\t\t\t\tif (!target) return;\n\t\t\t\t\t// Inside the picker → keep open (row clicks fire on `click`).\n\t\t\t\t\tif (popup.element.contains(target)) return;\n\t\t\t\t\t// Inside the editor → the suggestion plugin already closes it.\n\t\t\t\t\tconst editorDom = latestProps?.editor?.view?.dom as\n\t\t\t\t\t\t| HTMLElement\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (editorDom?.contains(target)) return;\n\t\t\t\t\t// Anywhere else → drop the typed \"@query\" (no refocus — clicking\n\t\t\t\t\t// away shouldn't yank focus back) and close.\n\t\t\t\t\tpickedRef.picked = true;\n\t\t\t\t\tif (latestProps?.editor && latestProps?.range) {\n\t\t\t\t\t\tlatestProps.editor.chain().deleteRange(latestProps.range).run();\n\t\t\t\t\t}\n\t\t\t\t\tpopup.hide();\n\t\t\t\t};\n\t\t\t\tdocument.addEventListener('mousedown', onDocMouseDown);\n\t\t\t},\n\t\t\tonUpdate: (props: any) => {\n\t\t\t\tlatestProps = props;\n\t\t\t\tcomponent.updateProps({\n\t\t\t\t\t...props,\n\t\t\t\t\trenderItem,\n\t\t\t\t\trenderDropdown,\n\t\t\t\t\tdismiss,\n\t\t\t\t});\n\t\t\t\tif (!props.items?.length) {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tpopup.show();\n\t\t\t\tpopup.updatePosition(props.clientRect);\n\t\t\t},\n\t\t\tonKeyDown: (props: any) => {\n\t\t\t\tif (props.event.key === 'Escape') {\n\t\t\t\t\tpopup.hide();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn (component.ref as any)?.onKeyDown(props) ?? false;\n\t\t\t},\n\t\t\tonExit: () => {\n\t\t\t\tif (onDocMouseDown) {\n\t\t\t\t\tdocument.removeEventListener('mousedown', onDocMouseDown);\n\t\t\t\t\tonDocMouseDown = null;\n\t\t\t\t}\n\t\t\t\tpopup.destroy();\n\t\t\t\tcomponent.destroy();\n\t\t\t\t// Nothing was picked → strip the orphan \"@query\" the user typed.\n\t\t\t\tif (\n\t\t\t\t\tremoveTriggerOnDismiss &&\n\t\t\t\t\t!pickedRef.picked &&\n\t\t\t\t\tlatestProps?.editor &&\n\t\t\t\t\tlatestProps?.range\n\t\t\t\t) {\n\t\t\t\t\tconst { editor, range } = latestProps;\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (!editor.isDestroyed) {\n\t\t\t\t\t\t\teditor.chain().deleteRange(range).run();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 0);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t};\n}\n\n/**\n * Builds a TipTap Mention extension.\n *\n * Each inserted node carries an optional `kind` attribute. When set, the chip is\n * rendered WITHOUT the trigger char (the `label` already encodes the full text)\n * and a `data-kind` attribute is emitted so CSS can colour it per kind. When\n * `kind` is null the legacy `${char}${label}` chip is rendered (back-compatible).\n */\nfunction buildMentionExtension(\n\tname: 'mentionAgent' | 'mentionTeam',\n\tcssClass: string,\n\tchar: '@' | '#',\n\titemsRef: { current: MentionItem[] },\n\tonSelect: ((item: MentionItem, char: '@' | '#') => void) | undefined,\n\toptions: MentionBuildOptions,\n) {\n\tconst pickedRef = { picked: false };\n\n\treturn Mention.extend({\n\t\tname,\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\t...this.parent?.(),\n\t\t\t\tkind: {\n\t\t\t\t\tdefault: null,\n\t\t\t\t\tparseHTML: (el: HTMLElement) => el.getAttribute('data-kind'),\n\t\t\t\t\trenderHTML: (attrs: Record<string, unknown>) =>\n\t\t\t\t\t\tattrs['kind'] ? { 'data-kind': String(attrs['kind']) } : {},\n\t\t\t\t},\n\t\t\t\t// Tool source bucket (manifest / shopify / …); drives the chip icon.\n\t\t\t\tsource: {\n\t\t\t\t\tdefault: null,\n\t\t\t\t\tparseHTML: (el: HTMLElement) => el.getAttribute('data-source'),\n\t\t\t\t\trenderHTML: (attrs: Record<string, unknown>) =>\n\t\t\t\t\t\tattrs['source'] ? { 'data-source': String(attrs['source']) } : {},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t// A React chip (with the leading source icon) only when the consumer asks for\n\t\t// it — otherwise the plain renderHTML chip is kept (unchanged for CRM etc.).\n\t\t...(options.renderChipIcon\n\t\t\t? {\n\t\t\t\t\taddNodeView() {\n\t\t\t\t\t\treturn ReactNodeViewRenderer(\n\t\t\t\t\t\t\tbuildMentionChipNodeView({\n\t\t\t\t\t\t\t\tcssClass,\n\t\t\t\t\t\t\t\tchar,\n\t\t\t\t\t\t\t\trenderChipIcon: options.renderChipIcon,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t }\n\t\t\t: {}),\n\t}).configure({\n\t\tHTMLAttributes: { class: cssClass },\n\t\trenderText: ({ options: opt, node }: any) =>\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\trenderHTML: ({ options: opt, node }: any) => [\n\t\t\t'span',\n\t\t\tmergeAttributes(\n\t\t\t\topt.HTMLAttributes,\n\t\t\t\tnode.attrs['kind'] ? { 'data-kind': String(node.attrs['kind']) } : {},\n\t\t\t\tnode.attrs['source']\n\t\t\t\t\t? { 'data-source': String(node.attrs['source']) }\n\t\t\t\t\t: {},\n\t\t\t),\n\t\t\t`${node.attrs['kind'] ? '' : opt.suggestion.char}${node.attrs['label']}`,\n\t\t],\n\t\tsuggestion: {\n\t\t\tchar,\n\t\t\tallowSpaces: true,\n\t\t\titems: ({ query }: { query: string }) =>\n\t\t\t\titemsRef.current.filter((a) =>\n\t\t\t\t\ta.label.toLowerCase().includes(query.toLowerCase()),\n\t\t\t\t),\n\t\t\tcommand: ({ editor, range, props }: any) => {\n\t\t\t\tpickedRef.picked = true;\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.deleteRange(range)\n\t\t\t\t\t.insertContent({\n\t\t\t\t\t\ttype: name,\n\t\t\t\t\t\tattrs: {\n\t\t\t\t\t\t\tid: props.id,\n\t\t\t\t\t\t\tlabel: props.label,\n\t\t\t\t\t\t\tkind: props.meta?.kind ?? null,\n\t\t\t\t\t\t\tsource: props.meta?.source ?? null,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\t.run();\n\t\t\t\tonSelect?.(props, char);\n\t\t\t},\n\t\t\trender: buildRender(options, pickedRef),\n\t\t},\n\t});\n}\n\nexport function buildAgentMentionExtension(\n\tagentsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n\trenderChipIcon?: (source: string | null, kind: string | null) => ReactNode,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionAgent',\n\t\t'bik-mention bik-mention--agent',\n\t\t'@',\n\t\tagentsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss, renderChipIcon },\n\t);\n}\n\nexport function buildTeamMentionExtension(\n\tteamsRef: { current: MentionItem[] },\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void,\n\trenderItem?: (item: MentionItem, isActive: boolean) => ReactNode,\n\trenderDropdown?: (props: MentionDropdownRenderProps) => ReactNode,\n\tremoveTriggerOnDismiss?: boolean,\n) {\n\treturn buildMentionExtension(\n\t\t'mentionTeam',\n\t\t'bik-mention bik-mention--team',\n\t\t'#',\n\t\tteamsRef,\n\t\tonSelect,\n\t\t{ renderItem, renderDropdown, removeTriggerOnDismiss },\n\t);\n}\n"],"names":["buildRender","options","pickedRef","renderItem","renderDropdown","removeTriggerOnDismiss","component","popup","latestProps","onDocMouseDown","dismiss","editor","range","props","ReactRenderer","MentionDropdown","createSuggestionPopup","event","target","buildMentionExtension","name","cssClass","char","itemsRef","onSelect","Mention","el","attrs","ReactNodeViewRenderer","buildMentionChipNodeView","opt","node","mergeAttributes","query","a","buildAgentMentionExtension","agentsRef","renderChipIcon","buildTeamMentionExtension","teamsRef"],"mappings":"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"}