@threadlabs/looma 0.1.16 → 0.1.18

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 (133) hide show
  1. package/README.md +2 -1
  2. package/dist/{chunk-SVINNT3E.js → chunk-DTQVRGVL.js} +29 -29
  3. package/dist/{chunk-G53JEAQK.js → chunk-SZJQ3NPX.js} +6 -3
  4. package/dist/chunk-YHXJC5M5.js +341 -0
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/looma.cjs.js +1 -1
  7. package/dist/cjs/{manager-BOpVXb92.js → manager-C9j3HZay.js} +5 -2
  8. package/dist/cjs/positioning-i0WrCAdF.js +384 -0
  9. package/dist/cjs/ui-affordance-scope.cjs.entry.js +3 -113
  10. package/dist/cjs/ui-context-menu.cjs.entry.js +43 -5
  11. package/dist/cjs/ui-dialog.cjs.entry.js +1 -1
  12. package/dist/cjs/ui-menu.cjs.entry.js +83 -2
  13. package/dist/cjs/ui-popover.cjs.entry.js +43 -3
  14. package/dist/cjs/ui-toast-region.cjs.entry.js +17 -2
  15. package/dist/cjs/ui-tooltip.cjs.entry.js +95 -27
  16. package/dist/cjs/ui-tree-item.cjs.entry.js +1 -1
  17. package/dist/collection/components/ui-context-menu/ui-context-menu.css +21 -4
  18. package/dist/collection/components/ui-context-menu/ui-context-menu.js +43 -4
  19. package/dist/collection/components/ui-menu/ui-menu.css +39 -0
  20. package/dist/collection/components/ui-menu/ui-menu.js +128 -1
  21. package/dist/collection/components/ui-popover/ui-popover.css +31 -0
  22. package/dist/collection/components/ui-popover/ui-popover.js +87 -1
  23. package/dist/collection/components/ui-toast-region/ui-toast-region.css +6 -0
  24. package/dist/collection/components/ui-toast-region/ui-toast-region.js +16 -1
  25. package/dist/collection/components/ui-tooltip/ui-tooltip.css +20 -0
  26. package/dist/collection/components/ui-tooltip/ui-tooltip.js +160 -25
  27. package/dist/collection/components/ui-tree-item/ui-tree-item.css +10 -6
  28. package/dist/collection/input-modality.js +24 -0
  29. package/dist/collection/overlay/manager.js +5 -2
  30. package/dist/collection/overlay/positioning.js +246 -0
  31. package/dist/components/p-CEYIKqYc.js +1 -0
  32. package/dist/components/p-DOulVJT7.js +1 -0
  33. package/dist/components/p-PM9a74r7.js +1 -0
  34. package/dist/components/ui-affordance-scope.js +1 -1
  35. package/dist/components/ui-context-menu.js +1 -1
  36. package/dist/components/ui-dialog.js +1 -1
  37. package/dist/components/ui-menu.js +1 -1
  38. package/dist/components/ui-popover.js +1 -1
  39. package/dist/components/ui-toast-region.js +1 -1
  40. package/dist/components/ui-tooltip.js +1 -1
  41. package/dist/components/ui-tree-item.js +1 -1
  42. package/dist/esm/loader.js +1 -1
  43. package/dist/esm/looma.js +1 -1
  44. package/dist/esm/{manager-CR7f2MQC.js → manager-PM9a74r7.js} +5 -2
  45. package/dist/esm/positioning-Bu0dmLBE.js +379 -0
  46. package/dist/esm/ui-affordance-scope.entry.js +1 -111
  47. package/dist/esm/ui-context-menu.entry.js +43 -5
  48. package/dist/esm/ui-dialog.entry.js +1 -1
  49. package/dist/esm/ui-menu.entry.js +83 -2
  50. package/dist/esm/ui-popover.entry.js +43 -3
  51. package/dist/esm/ui-toast-region.entry.js +17 -2
  52. package/dist/esm/ui-tooltip.entry.js +95 -27
  53. package/dist/esm/ui-tree-item.entry.js +1 -1
  54. package/dist/index.cjs +779 -59
  55. package/dist/index.d.cts +44 -1
  56. package/dist/index.d.ts +44 -1
  57. package/dist/index.js +235 -4
  58. package/dist/looma/looma.esm.js +1 -1
  59. package/dist/looma/p-063f5a89.entry.js +1 -0
  60. package/dist/looma/{p-c6721aba.entry.js → p-11083743.entry.js} +1 -1
  61. package/dist/looma/p-1674cda4.entry.js +1 -0
  62. package/dist/looma/p-2e6f791e.entry.js +1 -0
  63. package/dist/looma/p-54c41576.entry.js +1 -0
  64. package/dist/looma/p-9194a99d.entry.js +1 -0
  65. package/dist/looma/p-Bu0dmLBE.js +1 -0
  66. package/dist/looma/p-PM9a74r7.js +1 -0
  67. package/dist/looma/p-caa8fc7b.entry.js +1 -0
  68. package/dist/looma/{p-ef9ca2ed.entry.js → p-d01960c2.entry.js} +2 -2
  69. package/dist/types/components/ui-context-menu/ui-context-menu.d.ts +6 -0
  70. package/dist/types/components/ui-menu/ui-menu.d.ts +13 -0
  71. package/dist/types/components/ui-popover/ui-popover.d.ts +9 -0
  72. package/dist/types/components/ui-toast-region/ui-toast-region.d.ts +2 -0
  73. package/dist/types/components/ui-tooltip/ui-tooltip.d.ts +16 -1
  74. package/dist/types/components.d.ts +71 -0
  75. package/dist/types/input-modality.d.ts +6 -0
  76. package/dist/types/overlay/manager.d.ts +3 -0
  77. package/dist/types/overlay/positioning.d.ts +33 -0
  78. package/dist/ui-affordance-scope.entry-2W7ZKAGK.js +54 -0
  79. package/dist/{ui-avatar-group.entry-DQDP325O.js → ui-avatar-group.entry-SE5JG2FT.js} +1 -1
  80. package/dist/{ui-avatar.entry-WYIDMOFE.js → ui-avatar.entry-46JDI25A.js} +1 -1
  81. package/dist/{ui-badge.entry-VGHXPEDT.js → ui-badge.entry-U7G3MEC5.js} +1 -1
  82. package/dist/{ui-button.entry-LKPLOJ22.js → ui-button.entry-DELD6KMH.js} +1 -1
  83. package/dist/{ui-checkbox.entry-J74HEA22.js → ui-checkbox.entry-ZUG2P642.js} +1 -1
  84. package/dist/{ui-context-menu.entry-MQM2FCLI.js → ui-context-menu.entry-L4HTK3PV.js} +43 -6
  85. package/dist/{ui-dialog.entry-DQMMDO4Z.js → ui-dialog.entry-TQPYD2YI.js} +2 -2
  86. package/dist/{ui-disclosure.entry-ONF7UZDC.js → ui-disclosure.entry-23TII4YU.js} +1 -1
  87. package/dist/{ui-floating-action-button.entry-FKTGVC5T.js → ui-floating-action-button.entry-FOQYAFJI.js} +1 -1
  88. package/dist/{ui-form-field.entry-M3ISWQNU.js → ui-form-field.entry-SCPG4STY.js} +1 -1
  89. package/dist/{ui-icon-button.entry-AWFIQUHM.js → ui-icon-button.entry-U45ZVAC3.js} +1 -1
  90. package/dist/{ui-input.entry-JZ6RETMT.js → ui-input.entry-3AIA3G4C.js} +1 -1
  91. package/dist/{ui-menu-item.entry-5MFR5LFL.js → ui-menu-item.entry-3QO5TG2J.js} +1 -1
  92. package/dist/ui-menu.entry-JACWGDDG.js +184 -0
  93. package/dist/{ui-popover.entry-ELCMKO6Y.js → ui-popover.entry-2XP4H3S2.js} +46 -4
  94. package/dist/{ui-radio-group.entry-RJHUPPEM.js → ui-radio-group.entry-73IKFMDK.js} +1 -1
  95. package/dist/{ui-radio.entry-3VRDPOY4.js → ui-radio.entry-INJVXUKE.js} +1 -1
  96. package/dist/{ui-search-result-row.entry-J34YPAV7.js → ui-search-result-row.entry-4J732TDC.js} +1 -1
  97. package/dist/{ui-search-shell.entry-IJ4UUP27.js → ui-search-shell.entry-3C2WRVE2.js} +1 -1
  98. package/dist/{ui-select.entry-C6YD3HQ5.js → ui-select.entry-3ZLDGAKX.js} +1 -1
  99. package/dist/{ui-switch.entry-UZDF5QTI.js → ui-switch.entry-5MJRLR2P.js} +1 -1
  100. package/dist/{ui-tabs.entry-YRAKWOMR.js → ui-tabs.entry-F5H7OPBO.js} +1 -1
  101. package/dist/{ui-textarea.entry-JLDKFT3K.js → ui-textarea.entry-BNJ375JB.js} +1 -1
  102. package/dist/{ui-toast-region.entry-GC7C7KXF.js → ui-toast-region.entry-ZUIPJ2JH.js} +20 -3
  103. package/dist/ui-tooltip.entry-DZ4RMF35.js +214 -0
  104. package/dist/{ui-top-bar.entry-5W5UA5KV.js → ui-top-bar.entry-VKRXIUU6.js} +1 -1
  105. package/dist/{ui-tree-item.entry-3LM7IXIK.js → ui-tree-item.entry-NFUQ45OL.js} +2 -2
  106. package/dist/{ui-tree.entry-X4FU42A6.js → ui-tree.entry-H4CWDYI6.js} +1 -1
  107. package/editor/{chunk-RTHHTPWK.js → chunk-3QMBK3XZ.js} +245 -41
  108. package/editor/{chunk-OHD4OS32.js → chunk-OXFYYLUC.js} +632 -236
  109. package/editor/{chunk-CX4QDKSV.js → chunk-ZOUKEZ77.js} +21 -1
  110. package/editor/extensions/index.d.ts +49 -1
  111. package/editor/extensions/index.js +15 -3
  112. package/editor/index.d.ts +3 -2
  113. package/editor/index.js +16 -4
  114. package/editor/ui.d.ts +9 -1
  115. package/editor/ui.js +2 -2
  116. package/editor.css +173 -4
  117. package/package.json +1 -1
  118. package/styles.css +1 -7
  119. package/tokens.css +14 -2
  120. package/vue/editor/index.d.ts +103 -4
  121. package/vue/editor/index.js +199 -114
  122. package/dist/components/p-CR7f2MQC.js +0 -1
  123. package/dist/components/p-QiwSQmKJ.js +0 -1
  124. package/dist/looma/p-2ae73d5b.entry.js +0 -1
  125. package/dist/looma/p-3ac2e0d4.entry.js +0 -1
  126. package/dist/looma/p-65c25c94.entry.js +0 -1
  127. package/dist/looma/p-8c09c724.entry.js +0 -1
  128. package/dist/looma/p-95cd639d.entry.js +0 -1
  129. package/dist/looma/p-96f73d07.entry.js +0 -1
  130. package/dist/looma/p-CR7f2MQC.js +0 -1
  131. package/dist/ui-affordance-scope.entry-PFP2TDKO.js +0 -145
  132. package/dist/ui-menu.entry-IOEIDATQ.js +0 -98
  133. package/dist/ui-tooltip.entry-F26XDTYX.js +0 -145
@@ -1,6 +1,8 @@
1
1
  import {
2
- TABLE_CELL_BACKGROUND_PRESETS
3
- } from "./chunk-CX4QDKSV.js";
2
+ TABLE_CELL_BACKGROUND_PRESETS,
3
+ filterLoomaMentionItems,
4
+ normalizeMentionResultLimit
5
+ } from "./chunk-ZOUKEZ77.js";
4
6
 
5
7
  // src/extensions/preset.ts
6
8
  import { Extension as Extension7 } from "@tiptap/core";
@@ -4892,8 +4894,620 @@ var LoomaListBehavior = Extension6.create({
4892
4894
  }
4893
4895
  });
4894
4896
 
4897
+ // ../../node_modules/.pnpm/@tiptap+extension-mention@2.27.3_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27_e4d93fc6b40c97d74d1cbe40f638e38f/node_modules/@tiptap/extension-mention/dist/index.js
4898
+ import { Node as Node16, mergeAttributes as mergeAttributes21 } from "@tiptap/core";
4899
+ import { Node as Node$1 } from "@tiptap/pm/model";
4900
+
4901
+ // ../../node_modules/.pnpm/@tiptap+suggestion@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/@tiptap/suggestion/dist/index.js
4902
+ import { PluginKey as PluginKey5, Plugin as Plugin5 } from "@tiptap/pm/state";
4903
+ import { DecorationSet as DecorationSet3, Decoration as Decoration3 } from "@tiptap/pm/view";
4904
+ import { escapeForRegEx } from "@tiptap/core";
4905
+ function findSuggestionMatch(config) {
4906
+ var _a;
4907
+ const { char, allowSpaces: allowSpacesOption, allowToIncludeChar, allowedPrefixes, startOfLine, $position } = config;
4908
+ const allowSpaces = allowSpacesOption && !allowToIncludeChar;
4909
+ const escapedChar = escapeForRegEx(char);
4910
+ const suffix = new RegExp(`\\s${escapedChar}$`);
4911
+ const prefix = startOfLine ? "^" : "";
4912
+ const finalEscapedChar = allowToIncludeChar ? "" : escapedChar;
4913
+ const regexp = allowSpaces ? new RegExp(`${prefix}${escapedChar}.*?(?=\\s${finalEscapedChar}|$)`, "gm") : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s${finalEscapedChar}]*`, "gm");
4914
+ const text = ((_a = $position.nodeBefore) === null || _a === void 0 ? void 0 : _a.isText) && $position.nodeBefore.text;
4915
+ if (!text) {
4916
+ return null;
4917
+ }
4918
+ const textFrom = $position.pos - text.length;
4919
+ const match = Array.from(text.matchAll(regexp)).pop();
4920
+ if (!match || match.input === void 0 || match.index === void 0) {
4921
+ return null;
4922
+ }
4923
+ const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index);
4924
+ const matchPrefixIsAllowed = new RegExp(`^[${allowedPrefixes === null || allowedPrefixes === void 0 ? void 0 : allowedPrefixes.join("")}\0]?$`).test(matchPrefix);
4925
+ if (allowedPrefixes !== null && !matchPrefixIsAllowed) {
4926
+ return null;
4927
+ }
4928
+ const from = textFrom + match.index;
4929
+ let to = from + match[0].length;
4930
+ if (allowSpaces && suffix.test(text.slice(to - 1, to + 1))) {
4931
+ match[0] += " ";
4932
+ to += 1;
4933
+ }
4934
+ if (from < $position.pos && to >= $position.pos) {
4935
+ return {
4936
+ range: {
4937
+ from,
4938
+ to
4939
+ },
4940
+ query: match[0].slice(char.length),
4941
+ text: match[0]
4942
+ };
4943
+ }
4944
+ return null;
4945
+ }
4946
+ var SuggestionPluginKey = new PluginKey5("suggestion");
4947
+ function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = "@", allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [" "], startOfLine = false, decorationTag = "span", decorationClass = "suggestion", decorationContent = "", decorationEmptyClass = "is-empty", command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch }) {
4948
+ let props;
4949
+ const renderer = render === null || render === void 0 ? void 0 : render();
4950
+ const plugin = new Plugin5({
4951
+ key: pluginKey,
4952
+ view() {
4953
+ return {
4954
+ update: async (view, prevState) => {
4955
+ var _a, _b, _c, _d, _e, _f, _g;
4956
+ const prev = (_a = this.key) === null || _a === void 0 ? void 0 : _a.getState(prevState);
4957
+ const next = (_b = this.key) === null || _b === void 0 ? void 0 : _b.getState(view.state);
4958
+ const moved = prev.active && next.active && prev.range.from !== next.range.from;
4959
+ const started = !prev.active && next.active;
4960
+ const stopped = prev.active && !next.active;
4961
+ const changed = !started && !stopped && prev.query !== next.query;
4962
+ const handleStart = started || moved && changed;
4963
+ const handleChange = changed || moved;
4964
+ const handleExit = stopped || moved && changed;
4965
+ if (!handleStart && !handleChange && !handleExit) {
4966
+ return;
4967
+ }
4968
+ const state = handleExit && !handleStart ? prev : next;
4969
+ const decorationNode = view.dom.querySelector(`[data-decoration-id="${state.decorationId}"]`);
4970
+ props = {
4971
+ editor,
4972
+ range: state.range,
4973
+ query: state.query,
4974
+ text: state.text,
4975
+ items: [],
4976
+ command: (commandProps) => {
4977
+ return command({
4978
+ editor,
4979
+ range: state.range,
4980
+ props: commandProps
4981
+ });
4982
+ },
4983
+ decorationNode,
4984
+ // virtual node for popper.js or tippy.js
4985
+ // this can be used for building popups without a DOM node
4986
+ clientRect: decorationNode ? () => {
4987
+ var _a2;
4988
+ const { decorationId } = (_a2 = this.key) === null || _a2 === void 0 ? void 0 : _a2.getState(editor.state);
4989
+ const currentDecorationNode = view.dom.querySelector(`[data-decoration-id="${decorationId}"]`);
4990
+ return (currentDecorationNode === null || currentDecorationNode === void 0 ? void 0 : currentDecorationNode.getBoundingClientRect()) || null;
4991
+ } : null
4992
+ };
4993
+ if (handleStart) {
4994
+ (_c = renderer === null || renderer === void 0 ? void 0 : renderer.onBeforeStart) === null || _c === void 0 ? void 0 : _c.call(renderer, props);
4995
+ }
4996
+ if (handleChange) {
4997
+ (_d = renderer === null || renderer === void 0 ? void 0 : renderer.onBeforeUpdate) === null || _d === void 0 ? void 0 : _d.call(renderer, props);
4998
+ }
4999
+ if (handleChange || handleStart) {
5000
+ props.items = await items({
5001
+ editor,
5002
+ query: state.query
5003
+ });
5004
+ }
5005
+ if (handleExit) {
5006
+ (_e = renderer === null || renderer === void 0 ? void 0 : renderer.onExit) === null || _e === void 0 ? void 0 : _e.call(renderer, props);
5007
+ }
5008
+ if (handleChange) {
5009
+ (_f = renderer === null || renderer === void 0 ? void 0 : renderer.onUpdate) === null || _f === void 0 ? void 0 : _f.call(renderer, props);
5010
+ }
5011
+ if (handleStart) {
5012
+ (_g = renderer === null || renderer === void 0 ? void 0 : renderer.onStart) === null || _g === void 0 ? void 0 : _g.call(renderer, props);
5013
+ }
5014
+ },
5015
+ destroy: () => {
5016
+ var _a;
5017
+ if (!props) {
5018
+ return;
5019
+ }
5020
+ (_a = renderer === null || renderer === void 0 ? void 0 : renderer.onExit) === null || _a === void 0 ? void 0 : _a.call(renderer, props);
5021
+ }
5022
+ };
5023
+ },
5024
+ state: {
5025
+ // Initialize the plugin's internal state.
5026
+ init() {
5027
+ const state = {
5028
+ active: false,
5029
+ range: {
5030
+ from: 0,
5031
+ to: 0
5032
+ },
5033
+ query: null,
5034
+ text: null,
5035
+ composing: false
5036
+ };
5037
+ return state;
5038
+ },
5039
+ // Apply changes to the plugin state from a view transaction.
5040
+ apply(transaction, prev, _oldState, state) {
5041
+ const { isEditable } = editor;
5042
+ const { composing } = editor.view;
5043
+ const { selection } = transaction;
5044
+ const { empty, from } = selection;
5045
+ const next = { ...prev };
5046
+ next.composing = composing;
5047
+ if (isEditable && (empty || editor.view.composing)) {
5048
+ if ((from < prev.range.from || from > prev.range.to) && !composing && !prev.composing) {
5049
+ next.active = false;
5050
+ }
5051
+ const match = findSuggestionMatch$1({
5052
+ char,
5053
+ allowSpaces,
5054
+ allowToIncludeChar,
5055
+ allowedPrefixes,
5056
+ startOfLine,
5057
+ $position: selection.$from
5058
+ });
5059
+ const decorationId = `id_${Math.floor(Math.random() * 4294967295)}`;
5060
+ if (match && allow({
5061
+ editor,
5062
+ state,
5063
+ range: match.range,
5064
+ isActive: prev.active
5065
+ })) {
5066
+ next.active = true;
5067
+ next.decorationId = prev.decorationId ? prev.decorationId : decorationId;
5068
+ next.range = match.range;
5069
+ next.query = match.query;
5070
+ next.text = match.text;
5071
+ } else {
5072
+ next.active = false;
5073
+ }
5074
+ } else {
5075
+ next.active = false;
5076
+ }
5077
+ if (!next.active) {
5078
+ next.decorationId = null;
5079
+ next.range = { from: 0, to: 0 };
5080
+ next.query = null;
5081
+ next.text = null;
5082
+ }
5083
+ return next;
5084
+ }
5085
+ },
5086
+ props: {
5087
+ // Call the keydown hook if suggestion is active.
5088
+ handleKeyDown(view, event) {
5089
+ var _a;
5090
+ const { active, range } = plugin.getState(view.state);
5091
+ if (!active) {
5092
+ return false;
5093
+ }
5094
+ return ((_a = renderer === null || renderer === void 0 ? void 0 : renderer.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(renderer, { view, event, range })) || false;
5095
+ },
5096
+ // Setup decorator on the currently active suggestion.
5097
+ decorations(state) {
5098
+ const { active, range, decorationId, query } = plugin.getState(state);
5099
+ if (!active) {
5100
+ return null;
5101
+ }
5102
+ const isEmpty = !(query === null || query === void 0 ? void 0 : query.length);
5103
+ const classNames = [decorationClass];
5104
+ if (isEmpty) {
5105
+ classNames.push(decorationEmptyClass);
5106
+ }
5107
+ return DecorationSet3.create(state.doc, [
5108
+ Decoration3.inline(range.from, range.to, {
5109
+ nodeName: decorationTag,
5110
+ class: classNames.join(" "),
5111
+ "data-decoration-id": decorationId,
5112
+ "data-decoration-content": decorationContent
5113
+ })
5114
+ ]);
5115
+ }
5116
+ }
5117
+ });
5118
+ return plugin;
5119
+ }
5120
+
5121
+ // ../../node_modules/.pnpm/@tiptap+extension-mention@2.27.3_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27_e4d93fc6b40c97d74d1cbe40f638e38f/node_modules/@tiptap/extension-mention/dist/index.js
5122
+ import { PluginKey as PluginKey6 } from "@tiptap/pm/state";
5123
+ function getSuggestionOptions({ editor: tiptapEditor, overrideSuggestionOptions, extensionName, char = "@" }) {
5124
+ const pluginKey = new PluginKey6();
5125
+ return {
5126
+ editor: tiptapEditor,
5127
+ char,
5128
+ pluginKey,
5129
+ command: ({ editor, range, props }) => {
5130
+ var _a, _b, _c;
5131
+ const nodeAfter = editor.view.state.selection.$to.nodeAfter;
5132
+ const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(" ");
5133
+ if (overrideSpace) {
5134
+ range.to += 1;
5135
+ }
5136
+ editor.chain().focus().insertContentAt(range, [
5137
+ {
5138
+ type: extensionName,
5139
+ attrs: { ...props, mentionSuggestionChar: char }
5140
+ },
5141
+ {
5142
+ type: "text",
5143
+ text: " "
5144
+ }
5145
+ ]).run();
5146
+ (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
5147
+ },
5148
+ allow: ({ state, range }) => {
5149
+ const $from = state.doc.resolve(range.from);
5150
+ const type = state.schema.nodes[extensionName];
5151
+ const allow = !!$from.parent.type.contentMatch.matchType(type);
5152
+ return allow;
5153
+ },
5154
+ ...overrideSuggestionOptions
5155
+ };
5156
+ }
5157
+ function getSuggestions(options) {
5158
+ return (options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]).map((suggestion) => getSuggestionOptions({
5159
+ // @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility
5160
+ editor: options.editor,
5161
+ overrideSuggestionOptions: suggestion,
5162
+ extensionName: options.name,
5163
+ char: suggestion.char
5164
+ }));
5165
+ }
5166
+ function getSuggestionFromChar(options, char) {
5167
+ const suggestions = getSuggestions(options);
5168
+ const suggestion = suggestions.find((s) => s.char === char);
5169
+ if (suggestion) {
5170
+ return suggestion;
5171
+ }
5172
+ if (suggestions.length) {
5173
+ return suggestions[0];
5174
+ }
5175
+ return null;
5176
+ }
5177
+ var Mention = Node16.create({
5178
+ name: "mention",
5179
+ priority: 101,
5180
+ addOptions() {
5181
+ return {
5182
+ HTMLAttributes: {},
5183
+ renderText({ node, suggestion }) {
5184
+ var _a, _b;
5185
+ return `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : "@"}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`;
5186
+ },
5187
+ deleteTriggerWithBackspace: false,
5188
+ renderHTML({ options, node, suggestion }) {
5189
+ var _a, _b;
5190
+ return [
5191
+ "span",
5192
+ mergeAttributes21(this.HTMLAttributes, options.HTMLAttributes),
5193
+ `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : "@"}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`
5194
+ ];
5195
+ },
5196
+ suggestions: [],
5197
+ suggestion: {}
5198
+ };
5199
+ },
5200
+ group: "inline",
5201
+ inline: true,
5202
+ selectable: false,
5203
+ atom: true,
5204
+ addAttributes() {
5205
+ return {
5206
+ id: {
5207
+ default: null,
5208
+ parseHTML: (element) => element.getAttribute("data-id"),
5209
+ renderHTML: (attributes) => {
5210
+ if (!attributes.id) {
5211
+ return {};
5212
+ }
5213
+ return {
5214
+ "data-id": attributes.id
5215
+ };
5216
+ }
5217
+ },
5218
+ label: {
5219
+ default: null,
5220
+ parseHTML: (element) => element.getAttribute("data-label"),
5221
+ renderHTML: (attributes) => {
5222
+ if (!attributes.label) {
5223
+ return {};
5224
+ }
5225
+ return {
5226
+ "data-label": attributes.label
5227
+ };
5228
+ }
5229
+ },
5230
+ // When there are multiple types of mentions, this attribute helps distinguish them
5231
+ mentionSuggestionChar: {
5232
+ default: "@",
5233
+ parseHTML: (element) => element.getAttribute("data-mention-suggestion-char"),
5234
+ renderHTML: (attributes) => {
5235
+ return {
5236
+ "data-mention-suggestion-char": attributes.mentionSuggestionChar
5237
+ };
5238
+ }
5239
+ }
5240
+ };
5241
+ },
5242
+ parseHTML() {
5243
+ return [
5244
+ {
5245
+ tag: `span[data-type="${this.name}"]`
5246
+ }
5247
+ ];
5248
+ },
5249
+ renderHTML({ node, HTMLAttributes }) {
5250
+ const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar);
5251
+ if (this.options.renderLabel !== void 0) {
5252
+ console.warn("renderLabel is deprecated use renderText and renderHTML instead");
5253
+ return [
5254
+ "span",
5255
+ mergeAttributes21({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
5256
+ this.options.renderLabel({
5257
+ options: this.options,
5258
+ node,
5259
+ suggestion
5260
+ })
5261
+ ];
5262
+ }
5263
+ const mergedOptions = { ...this.options };
5264
+ mergedOptions.HTMLAttributes = mergeAttributes21({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes);
5265
+ const html = this.options.renderHTML({
5266
+ options: mergedOptions,
5267
+ node,
5268
+ suggestion
5269
+ });
5270
+ if (typeof html === "string") {
5271
+ return [
5272
+ "span",
5273
+ mergeAttributes21({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
5274
+ html
5275
+ ];
5276
+ }
5277
+ return html;
5278
+ },
5279
+ renderText({ node }) {
5280
+ const args = {
5281
+ options: this.options,
5282
+ node,
5283
+ suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar)
5284
+ };
5285
+ if (this.options.renderLabel !== void 0) {
5286
+ console.warn("renderLabel is deprecated use renderText and renderHTML instead");
5287
+ return this.options.renderLabel(args);
5288
+ }
5289
+ return this.options.renderText(args);
5290
+ },
5291
+ addKeyboardShortcuts() {
5292
+ return {
5293
+ Backspace: () => this.editor.commands.command(({ tr: tr2, state }) => {
5294
+ let isMention = false;
5295
+ const { selection } = state;
5296
+ const { empty, anchor } = selection;
5297
+ if (!empty) {
5298
+ return false;
5299
+ }
5300
+ state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
5301
+ if (node.type.name === this.name) {
5302
+ isMention = true;
5303
+ tr2.insertText(this.options.deleteTriggerWithBackspace ? "" : this.options.suggestion.char || "", pos, pos + node.nodeSize);
5304
+ return false;
5305
+ }
5306
+ });
5307
+ let mentionNode = new Node$1();
5308
+ let mentionPos = 0;
5309
+ state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
5310
+ if (node.type.name === this.name) {
5311
+ isMention = true;
5312
+ mentionNode = node;
5313
+ mentionPos = pos;
5314
+ return false;
5315
+ }
5316
+ });
5317
+ if (isMention) {
5318
+ tr2.insertText(this.options.deleteTriggerWithBackspace ? "" : mentionNode.attrs.mentionSuggestionChar, mentionPos, mentionPos + mentionNode.nodeSize);
5319
+ }
5320
+ return isMention;
5321
+ })
5322
+ };
5323
+ },
5324
+ addProseMirrorPlugins() {
5325
+ return getSuggestions(this).map(Suggestion);
5326
+ }
5327
+ });
5328
+
5329
+ // src/extensions/mention.ts
5330
+ import { PluginKey as PluginKey7 } from "@tiptap/pm/state";
5331
+ var EMPTY_STATE = {
5332
+ active: false,
5333
+ items: [],
5334
+ selectedIndex: 0,
5335
+ query: "",
5336
+ rect: null,
5337
+ loading: false,
5338
+ highlight: null,
5339
+ select: null
5340
+ };
5341
+ var LoomaMentionSuggestionPluginKey = new PluginKey7(
5342
+ "loomaMentionSuggestion"
5343
+ );
5344
+ var LoomaMentionNode = Mention.extend({
5345
+ addAttributes() {
5346
+ const parentAttributes = this.parent?.() ?? {};
5347
+ const { mentionSuggestionChar: _trigger, ...durableAttributes } = parentAttributes;
5348
+ return durableAttributes;
5349
+ }
5350
+ });
5351
+ async function resolveMentionItems(source2, query, limit) {
5352
+ try {
5353
+ const resolved = typeof source2 === "function" ? await source2(query, { limit }) : source2 ?? [];
5354
+ return filterLoomaMentionItems(resolved, query, limit);
5355
+ } catch {
5356
+ return [];
5357
+ }
5358
+ }
5359
+ function createLoomaMentionExtension(options = {}) {
5360
+ const limit = normalizeMentionResultLimit(options.limit);
5361
+ const menuId = options.menuId ?? "ui-editor-mention-menu";
5362
+ return LoomaMentionNode.configure({
5363
+ HTMLAttributes: { class: "looma-mention" },
5364
+ renderText: ({ node }) => `@${node.attrs.label ?? node.attrs.id}`,
5365
+ renderHTML: ({ options: mentionOptions, node }) => [
5366
+ "span",
5367
+ mentionOptions.HTMLAttributes,
5368
+ `@${node.attrs.label ?? node.attrs.id}`
5369
+ ],
5370
+ suggestion: {
5371
+ pluginKey: LoomaMentionSuggestionPluginKey,
5372
+ char: "@",
5373
+ allowSpaces: false,
5374
+ startOfLine: false,
5375
+ items: ({ query }) => resolveMentionItems(options.items, query, limit),
5376
+ render: () => {
5377
+ let selectedIndex = 0;
5378
+ let currentProps = null;
5379
+ let dismissedFrom = null;
5380
+ let a11yOwner = null;
5381
+ const previousA11y = /* @__PURE__ */ new Map();
5382
+ const restoreEditorA11y = () => {
5383
+ if (!a11yOwner) return;
5384
+ for (const [name, value] of previousA11y) {
5385
+ if (value === null) a11yOwner.removeAttribute(name);
5386
+ else a11yOwner.setAttribute(name, value);
5387
+ }
5388
+ previousA11y.clear();
5389
+ a11yOwner = null;
5390
+ };
5391
+ const syncEditorA11y = (props) => {
5392
+ const owner = props.editor.view.dom;
5393
+ if (a11yOwner !== owner) {
5394
+ restoreEditorA11y();
5395
+ a11yOwner = owner;
5396
+ for (const name of [
5397
+ "aria-autocomplete",
5398
+ "aria-controls",
5399
+ "aria-expanded",
5400
+ "aria-activedescendant"
5401
+ ]) previousA11y.set(name, owner.getAttribute(name));
5402
+ }
5403
+ owner.setAttribute("aria-autocomplete", "list");
5404
+ owner.setAttribute("aria-controls", menuId);
5405
+ owner.setAttribute("aria-expanded", "true");
5406
+ if (props.items[selectedIndex]) {
5407
+ owner.setAttribute("aria-activedescendant", `${menuId}-option-${selectedIndex}`);
5408
+ } else {
5409
+ owner.removeAttribute("aria-activedescendant");
5410
+ }
5411
+ };
5412
+ const isCurrent = (props) => {
5413
+ const state = LoomaMentionSuggestionPluginKey.getState(
5414
+ props.editor.state
5415
+ );
5416
+ return state?.active === true && state.query === props.query && state.range?.from === props.range.from && state.range?.to === props.range.to;
5417
+ };
5418
+ const publish = (props, loading = false) => {
5419
+ if (!props) {
5420
+ restoreEditorA11y();
5421
+ options.onStateChange?.({ ...EMPTY_STATE });
5422
+ return;
5423
+ }
5424
+ if (!isCurrent(props) || dismissedFrom === props.range.from) return;
5425
+ if (!loading && props.items.length === 0) restoreEditorA11y();
5426
+ else syncEditorA11y(props);
5427
+ options.onStateChange?.({
5428
+ active: true,
5429
+ items: props.items,
5430
+ selectedIndex,
5431
+ query: props.query,
5432
+ rect: props.clientRect?.() ?? null,
5433
+ loading,
5434
+ highlight: (index) => {
5435
+ if (index >= 0 && index < props.items.length) {
5436
+ selectedIndex = index;
5437
+ syncEditorA11y(props);
5438
+ }
5439
+ },
5440
+ select: (index) => {
5441
+ const item = props.items[index];
5442
+ if (item) props.command({ id: item.id, label: item.label });
5443
+ }
5444
+ });
5445
+ };
5446
+ return {
5447
+ onBeforeStart: (props) => {
5448
+ currentProps = props;
5449
+ selectedIndex = 0;
5450
+ publish(props, true);
5451
+ },
5452
+ onStart: (props) => {
5453
+ if (!isCurrent(props) || dismissedFrom === props.range.from) return;
5454
+ currentProps = props;
5455
+ selectedIndex = 0;
5456
+ publish(props);
5457
+ },
5458
+ onBeforeUpdate: (props) => {
5459
+ if (dismissedFrom === props.range.from) return;
5460
+ currentProps = props;
5461
+ selectedIndex = 0;
5462
+ publish(props, true);
5463
+ },
5464
+ onUpdate: (props) => {
5465
+ if (!isCurrent(props) || dismissedFrom === props.range.from) return;
5466
+ currentProps = props;
5467
+ if (selectedIndex >= props.items.length) selectedIndex = 0;
5468
+ publish(props);
5469
+ },
5470
+ onKeyDown: ({ event, range }) => {
5471
+ if (event.key === "Escape") {
5472
+ dismissedFrom = range.from;
5473
+ currentProps = null;
5474
+ publish(null);
5475
+ return true;
5476
+ }
5477
+ if (!currentProps) return false;
5478
+ if (event.key === "ArrowDown") {
5479
+ if (currentProps.items.length === 0) return false;
5480
+ selectedIndex = (selectedIndex + 1) % Math.max(1, currentProps.items.length);
5481
+ publish(currentProps);
5482
+ return true;
5483
+ }
5484
+ if (event.key === "ArrowUp") {
5485
+ if (currentProps.items.length === 0) return false;
5486
+ selectedIndex = (selectedIndex - 1 + currentProps.items.length) % Math.max(1, currentProps.items.length);
5487
+ publish(currentProps);
5488
+ return true;
5489
+ }
5490
+ if (event.key === "Enter") {
5491
+ const item = currentProps.items[selectedIndex];
5492
+ if (!item) return false;
5493
+ currentProps.command({ id: item.id, label: item.label });
5494
+ return true;
5495
+ }
5496
+ return false;
5497
+ },
5498
+ onExit: () => {
5499
+ dismissedFrom = null;
5500
+ currentProps = null;
5501
+ publish(null);
5502
+ }
5503
+ };
5504
+ }
5505
+ }
5506
+ });
5507
+ }
5508
+
4895
5509
  // ../../node_modules/.pnpm/@tiptap+extension-table@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/@tiptap/extension-table/dist/index.js
4896
- import { findParentNodeClosestToPos, Node as Node16, mergeAttributes as mergeAttributes21, callOrReturn as callOrReturn2, getExtensionField as getExtensionField2 } from "@tiptap/core";
5510
+ import { findParentNodeClosestToPos, Node as Node17, mergeAttributes as mergeAttributes22, callOrReturn as callOrReturn2, getExtensionField as getExtensionField2 } from "@tiptap/core";
4897
5511
  import { TextSelection as TextSelection3 } from "@tiptap/pm/state";
4898
5512
  import { CellSelection, addColumnBefore, addColumnAfter, deleteColumn, addRowBefore, addRowAfter, deleteRow, deleteTable, mergeCells, splitCell, toggleHeader, toggleHeaderCell, setCellAttr, goToNextCell, fixTables, columnResizing, tableEditing } from "@tiptap/pm/tables";
4899
5513
  function getColStyleDeclaration(minWidth, width) {
@@ -5066,7 +5680,7 @@ var deleteTableWhenAllCellsSelected = ({ editor }) => {
5066
5680
  editor.commands.deleteTable();
5067
5681
  return true;
5068
5682
  };
5069
- var Table = Node16.create({
5683
+ var Table = Node17.create({
5070
5684
  name: "table",
5071
5685
  // @ts-ignore
5072
5686
  addOptions() {
@@ -5093,7 +5707,7 @@ var Table = Node16.create({
5093
5707
  const { colgroup, tableWidth, tableMinWidth } = createColGroup(node, this.options.cellMinWidth);
5094
5708
  const table = [
5095
5709
  "table",
5096
- mergeAttributes21(this.options.HTMLAttributes, HTMLAttributes, {
5710
+ mergeAttributes22(this.options.HTMLAttributes, HTMLAttributes, {
5097
5711
  style: tableWidth ? `width: ${tableWidth}` : `min-width: ${tableMinWidth}`
5098
5712
  }),
5099
5713
  colgroup,
@@ -5225,8 +5839,8 @@ var Table = Node16.create({
5225
5839
  });
5226
5840
 
5227
5841
  // ../../node_modules/.pnpm/@tiptap+extension-table-cell@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2_/node_modules/@tiptap/extension-table-cell/dist/index.js
5228
- import { Node as Node17, mergeAttributes as mergeAttributes22 } from "@tiptap/core";
5229
- var TableCell = Node17.create({
5842
+ import { Node as Node18, mergeAttributes as mergeAttributes23 } from "@tiptap/core";
5843
+ var TableCell = Node18.create({
5230
5844
  name: "tableCell",
5231
5845
  addOptions() {
5232
5846
  return {
@@ -5260,13 +5874,13 @@ var TableCell = Node17.create({
5260
5874
  ];
5261
5875
  },
5262
5876
  renderHTML({ HTMLAttributes }) {
5263
- return ["td", mergeAttributes22(this.options.HTMLAttributes, HTMLAttributes), 0];
5877
+ return ["td", mergeAttributes23(this.options.HTMLAttributes, HTMLAttributes), 0];
5264
5878
  }
5265
5879
  });
5266
5880
 
5267
5881
  // ../../node_modules/.pnpm/@tiptap+extension-table-header@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2_/node_modules/@tiptap/extension-table-header/dist/index.js
5268
- import { Node as Node18, mergeAttributes as mergeAttributes23 } from "@tiptap/core";
5269
- var TableHeader = Node18.create({
5882
+ import { Node as Node19, mergeAttributes as mergeAttributes24 } from "@tiptap/core";
5883
+ var TableHeader = Node19.create({
5270
5884
  name: "tableHeader",
5271
5885
  addOptions() {
5272
5886
  return {
@@ -5300,7 +5914,7 @@ var TableHeader = Node18.create({
5300
5914
  ];
5301
5915
  },
5302
5916
  renderHTML({ HTMLAttributes }) {
5303
- return ["th", mergeAttributes23(this.options.HTMLAttributes, HTMLAttributes), 0];
5917
+ return ["th", mergeAttributes24(this.options.HTMLAttributes, HTMLAttributes), 0];
5304
5918
  }
5305
5919
  });
5306
5920
 
@@ -5432,7 +6046,8 @@ function getDefaultEditorExtensions(options = {}) {
5432
6046
  const {
5433
6047
  placeholder = "Type \u201C/\u201D for commands, or start writing\u2026",
5434
6048
  linkOpenOnClick = false,
5435
- imageInline = false
6049
+ imageInline = false,
6050
+ mention = createLoomaMentionExtension()
5436
6051
  } = options;
5437
6052
  return [
5438
6053
  Document,
@@ -5467,6 +6082,7 @@ function getDefaultEditorExtensions(options = {}) {
5467
6082
  placeholder: ({ node }) => node.type.name === "paragraph" ? placeholder : "",
5468
6083
  emptyNodeClass: "is-editor-empty"
5469
6084
  }),
6085
+ ...mention ? [mention] : [],
5470
6086
  LoomaTableKit,
5471
6087
  LoomaListBehavior
5472
6088
  ];
@@ -5783,228 +6399,6 @@ function handleTableOverlayAction(editor, detail) {
5783
6399
 
5784
6400
  // src/extensions/slash-command.ts
5785
6401
  import { Extension as Extension8 } from "@tiptap/core";
5786
-
5787
- // ../../node_modules/.pnpm/@tiptap+suggestion@2.27.2_@tiptap+core@2.27.2_@tiptap+pm@2.27.2__@tiptap+pm@2.27.2/node_modules/@tiptap/suggestion/dist/index.js
5788
- import { PluginKey as PluginKey5, Plugin as Plugin5 } from "@tiptap/pm/state";
5789
- import { DecorationSet as DecorationSet3, Decoration as Decoration3 } from "@tiptap/pm/view";
5790
- import { escapeForRegEx } from "@tiptap/core";
5791
- function findSuggestionMatch(config) {
5792
- var _a;
5793
- const { char, allowSpaces: allowSpacesOption, allowToIncludeChar, allowedPrefixes, startOfLine, $position } = config;
5794
- const allowSpaces = allowSpacesOption && !allowToIncludeChar;
5795
- const escapedChar = escapeForRegEx(char);
5796
- const suffix = new RegExp(`\\s${escapedChar}$`);
5797
- const prefix = startOfLine ? "^" : "";
5798
- const finalEscapedChar = allowToIncludeChar ? "" : escapedChar;
5799
- const regexp = allowSpaces ? new RegExp(`${prefix}${escapedChar}.*?(?=\\s${finalEscapedChar}|$)`, "gm") : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\s${finalEscapedChar}]*`, "gm");
5800
- const text = ((_a = $position.nodeBefore) === null || _a === void 0 ? void 0 : _a.isText) && $position.nodeBefore.text;
5801
- if (!text) {
5802
- return null;
5803
- }
5804
- const textFrom = $position.pos - text.length;
5805
- const match = Array.from(text.matchAll(regexp)).pop();
5806
- if (!match || match.input === void 0 || match.index === void 0) {
5807
- return null;
5808
- }
5809
- const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index);
5810
- const matchPrefixIsAllowed = new RegExp(`^[${allowedPrefixes === null || allowedPrefixes === void 0 ? void 0 : allowedPrefixes.join("")}\0]?$`).test(matchPrefix);
5811
- if (allowedPrefixes !== null && !matchPrefixIsAllowed) {
5812
- return null;
5813
- }
5814
- const from = textFrom + match.index;
5815
- let to = from + match[0].length;
5816
- if (allowSpaces && suffix.test(text.slice(to - 1, to + 1))) {
5817
- match[0] += " ";
5818
- to += 1;
5819
- }
5820
- if (from < $position.pos && to >= $position.pos) {
5821
- return {
5822
- range: {
5823
- from,
5824
- to
5825
- },
5826
- query: match[0].slice(char.length),
5827
- text: match[0]
5828
- };
5829
- }
5830
- return null;
5831
- }
5832
- var SuggestionPluginKey = new PluginKey5("suggestion");
5833
- function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = "@", allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [" "], startOfLine = false, decorationTag = "span", decorationClass = "suggestion", decorationContent = "", decorationEmptyClass = "is-empty", command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch }) {
5834
- let props;
5835
- const renderer = render === null || render === void 0 ? void 0 : render();
5836
- const plugin = new Plugin5({
5837
- key: pluginKey,
5838
- view() {
5839
- return {
5840
- update: async (view, prevState) => {
5841
- var _a, _b, _c, _d, _e, _f, _g;
5842
- const prev = (_a = this.key) === null || _a === void 0 ? void 0 : _a.getState(prevState);
5843
- const next = (_b = this.key) === null || _b === void 0 ? void 0 : _b.getState(view.state);
5844
- const moved = prev.active && next.active && prev.range.from !== next.range.from;
5845
- const started = !prev.active && next.active;
5846
- const stopped = prev.active && !next.active;
5847
- const changed = !started && !stopped && prev.query !== next.query;
5848
- const handleStart = started || moved && changed;
5849
- const handleChange = changed || moved;
5850
- const handleExit = stopped || moved && changed;
5851
- if (!handleStart && !handleChange && !handleExit) {
5852
- return;
5853
- }
5854
- const state = handleExit && !handleStart ? prev : next;
5855
- const decorationNode = view.dom.querySelector(`[data-decoration-id="${state.decorationId}"]`);
5856
- props = {
5857
- editor,
5858
- range: state.range,
5859
- query: state.query,
5860
- text: state.text,
5861
- items: [],
5862
- command: (commandProps) => {
5863
- return command({
5864
- editor,
5865
- range: state.range,
5866
- props: commandProps
5867
- });
5868
- },
5869
- decorationNode,
5870
- // virtual node for popper.js or tippy.js
5871
- // this can be used for building popups without a DOM node
5872
- clientRect: decorationNode ? () => {
5873
- var _a2;
5874
- const { decorationId } = (_a2 = this.key) === null || _a2 === void 0 ? void 0 : _a2.getState(editor.state);
5875
- const currentDecorationNode = view.dom.querySelector(`[data-decoration-id="${decorationId}"]`);
5876
- return (currentDecorationNode === null || currentDecorationNode === void 0 ? void 0 : currentDecorationNode.getBoundingClientRect()) || null;
5877
- } : null
5878
- };
5879
- if (handleStart) {
5880
- (_c = renderer === null || renderer === void 0 ? void 0 : renderer.onBeforeStart) === null || _c === void 0 ? void 0 : _c.call(renderer, props);
5881
- }
5882
- if (handleChange) {
5883
- (_d = renderer === null || renderer === void 0 ? void 0 : renderer.onBeforeUpdate) === null || _d === void 0 ? void 0 : _d.call(renderer, props);
5884
- }
5885
- if (handleChange || handleStart) {
5886
- props.items = await items({
5887
- editor,
5888
- query: state.query
5889
- });
5890
- }
5891
- if (handleExit) {
5892
- (_e = renderer === null || renderer === void 0 ? void 0 : renderer.onExit) === null || _e === void 0 ? void 0 : _e.call(renderer, props);
5893
- }
5894
- if (handleChange) {
5895
- (_f = renderer === null || renderer === void 0 ? void 0 : renderer.onUpdate) === null || _f === void 0 ? void 0 : _f.call(renderer, props);
5896
- }
5897
- if (handleStart) {
5898
- (_g = renderer === null || renderer === void 0 ? void 0 : renderer.onStart) === null || _g === void 0 ? void 0 : _g.call(renderer, props);
5899
- }
5900
- },
5901
- destroy: () => {
5902
- var _a;
5903
- if (!props) {
5904
- return;
5905
- }
5906
- (_a = renderer === null || renderer === void 0 ? void 0 : renderer.onExit) === null || _a === void 0 ? void 0 : _a.call(renderer, props);
5907
- }
5908
- };
5909
- },
5910
- state: {
5911
- // Initialize the plugin's internal state.
5912
- init() {
5913
- const state = {
5914
- active: false,
5915
- range: {
5916
- from: 0,
5917
- to: 0
5918
- },
5919
- query: null,
5920
- text: null,
5921
- composing: false
5922
- };
5923
- return state;
5924
- },
5925
- // Apply changes to the plugin state from a view transaction.
5926
- apply(transaction, prev, _oldState, state) {
5927
- const { isEditable } = editor;
5928
- const { composing } = editor.view;
5929
- const { selection } = transaction;
5930
- const { empty, from } = selection;
5931
- const next = { ...prev };
5932
- next.composing = composing;
5933
- if (isEditable && (empty || editor.view.composing)) {
5934
- if ((from < prev.range.from || from > prev.range.to) && !composing && !prev.composing) {
5935
- next.active = false;
5936
- }
5937
- const match = findSuggestionMatch$1({
5938
- char,
5939
- allowSpaces,
5940
- allowToIncludeChar,
5941
- allowedPrefixes,
5942
- startOfLine,
5943
- $position: selection.$from
5944
- });
5945
- const decorationId = `id_${Math.floor(Math.random() * 4294967295)}`;
5946
- if (match && allow({
5947
- editor,
5948
- state,
5949
- range: match.range,
5950
- isActive: prev.active
5951
- })) {
5952
- next.active = true;
5953
- next.decorationId = prev.decorationId ? prev.decorationId : decorationId;
5954
- next.range = match.range;
5955
- next.query = match.query;
5956
- next.text = match.text;
5957
- } else {
5958
- next.active = false;
5959
- }
5960
- } else {
5961
- next.active = false;
5962
- }
5963
- if (!next.active) {
5964
- next.decorationId = null;
5965
- next.range = { from: 0, to: 0 };
5966
- next.query = null;
5967
- next.text = null;
5968
- }
5969
- return next;
5970
- }
5971
- },
5972
- props: {
5973
- // Call the keydown hook if suggestion is active.
5974
- handleKeyDown(view, event) {
5975
- var _a;
5976
- const { active, range } = plugin.getState(view.state);
5977
- if (!active) {
5978
- return false;
5979
- }
5980
- return ((_a = renderer === null || renderer === void 0 ? void 0 : renderer.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(renderer, { view, event, range })) || false;
5981
- },
5982
- // Setup decorator on the currently active suggestion.
5983
- decorations(state) {
5984
- const { active, range, decorationId, query } = plugin.getState(state);
5985
- if (!active) {
5986
- return null;
5987
- }
5988
- const isEmpty = !(query === null || query === void 0 ? void 0 : query.length);
5989
- const classNames = [decorationClass];
5990
- if (isEmpty) {
5991
- classNames.push(decorationEmptyClass);
5992
- }
5993
- return DecorationSet3.create(state.doc, [
5994
- Decoration3.inline(range.from, range.to, {
5995
- nodeName: decorationTag,
5996
- class: classNames.join(" "),
5997
- "data-decoration-id": decorationId,
5998
- "data-decoration-content": decorationContent
5999
- })
6000
- ]);
6001
- }
6002
- }
6003
- });
6004
- return plugin;
6005
- }
6006
-
6007
- // src/extensions/slash-command.ts
6008
6402
  function getDefaultSlashCommands(onOpenImagePicker) {
6009
6403
  return [
6010
6404
  {
@@ -6109,7 +6503,7 @@ function getDefaultSlashCommands(onOpenImagePicker) {
6109
6503
  }
6110
6504
  ];
6111
6505
  }
6112
- var EMPTY_STATE = {
6506
+ var EMPTY_STATE2 = {
6113
6507
  active: false,
6114
6508
  items: [],
6115
6509
  selectedIndex: 0,
@@ -6129,7 +6523,7 @@ var LoomaSlashCommand = Extension8.create({
6129
6523
  let currentProps = null;
6130
6524
  const publish = (props) => {
6131
6525
  if (!props) {
6132
- this.options.onStateChange?.({ ...EMPTY_STATE });
6526
+ this.options.onStateChange?.({ ...EMPTY_STATE2 });
6133
6527
  return;
6134
6528
  }
6135
6529
  this.options.onStateChange?.({
@@ -6214,6 +6608,8 @@ function createLoomaSlashCommandExtension(options = {}) {
6214
6608
  }
6215
6609
 
6216
6610
  export {
6611
+ LoomaMentionSuggestionPluginKey,
6612
+ createLoomaMentionExtension,
6217
6613
  LoomaTable,
6218
6614
  LoomaTableHeader,
6219
6615
  LoomaTableCell,