agentation-vue 0.2.6 → 0.2.12

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 (33) hide show
  1. package/README.md +94 -0
  2. package/dist/AgentationVue.vue +270 -60
  3. package/dist/components/AgentationToolbar.d.vue.ts +2 -0
  4. package/dist/components/AgentationToolbar.vue +12 -3
  5. package/dist/components/AgentationToolbar.vue.d.ts +2 -0
  6. package/dist/components/AnnotationInput.d.vue.ts +2 -0
  7. package/dist/components/AnnotationInput.vue +88 -16
  8. package/dist/components/AnnotationInput.vue.d.ts +2 -0
  9. package/dist/components/AnnotationMarker.d.vue.ts +1 -0
  10. package/dist/components/AnnotationMarker.vue +12 -3
  11. package/dist/components/AnnotationMarker.vue.d.ts +1 -0
  12. package/dist/components/MentionDropdown.d.vue.ts +16 -0
  13. package/dist/components/MentionDropdown.vue +41 -0
  14. package/dist/components/MentionDropdown.vue.d.ts +16 -0
  15. package/dist/components/SettingsPanel.vue +26 -3
  16. package/dist/components/SettingsPopover.vue +3 -5
  17. package/dist/composables/useAnnotations.d.ts +2 -0
  18. package/dist/composables/useAnnotations.mjs +6 -1
  19. package/dist/composables/useKeyboardShortcuts.mjs +22 -8
  20. package/dist/composables/useMentionDropdown.d.ts +21 -0
  21. package/dist/composables/useMentionDropdown.mjs +162 -0
  22. package/dist/composables/useOutputFormatter.mjs +2 -1
  23. package/dist/composables/usePeekMode.d.ts +14 -0
  24. package/dist/composables/usePeekMode.mjs +119 -0
  25. package/dist/composables/useSettings.d.ts +1 -0
  26. package/dist/composables/useSettings.mjs +2 -1
  27. package/dist/constants.d.ts +2 -0
  28. package/dist/constants.mjs +3 -0
  29. package/dist/styles/agentation.css +1 -1
  30. package/dist/types.d.ts +1 -0
  31. package/dist/utils/mention.d.ts +13 -0
  32. package/dist/utils/mention.mjs +46 -0
  33. package/package.json +2 -2
@@ -1,3 +1,4 @@
1
+ import type { MentionCandidate } from '../utils/mention';
1
2
  type __VLS_Props = {
2
3
  position: {
3
4
  x: number;
@@ -8,6 +9,7 @@ type __VLS_Props = {
8
9
  computedStyles?: Record<string, string>;
9
10
  initialComment?: string;
10
11
  isEditing?: boolean;
12
+ mentionCandidates?: MentionCandidate[];
11
13
  };
12
14
  declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
13
15
  cancel: () => any;
@@ -1,6 +1,9 @@
1
1
  <script setup>
2
- import { computed, onMounted, ref } from "vue-demi";
2
+ import { computed, onMounted, ref, toRef } from "vue-demi";
3
+ import { useMentionDropdown } from "../composables/useMentionDropdown.mjs";
4
+ import { hydrateMentions, serializeMentions } from "../utils/mention.mjs";
3
5
  import ComponentChain from "./ComponentChain.vue";
6
+ import MentionDropdown from "./MentionDropdown.vue";
4
7
  import VaButton from "./VaButton.vue";
5
8
  import VaIcon from "./VaIcon.vue";
6
9
  const props = defineProps({
@@ -9,12 +12,16 @@ const props = defineProps({
9
12
  componentChain: { type: String, required: false },
10
13
  computedStyles: { type: Object, required: false },
11
14
  initialComment: { type: String, required: false },
12
- isEditing: { type: Boolean, required: false }
15
+ isEditing: { type: Boolean, required: false },
16
+ mentionCandidates: { type: Array, required: false }
13
17
  });
14
18
  const emit = defineEmits(["add", "cancel", "delete"]);
15
- const comment = ref(props.initialComment || "");
16
19
  const inputEl = ref(null);
20
+ const commentText = ref(props.initialComment || "");
17
21
  const computedStyleEntries = computed(() => Object.entries(props.computedStyles || {}));
22
+ const candidates = toRef(props, "mentionCandidates");
23
+ const safeCandidates = computed(() => candidates.value || []);
24
+ const mention = useMentionDropdown(inputEl, safeCandidates);
18
25
  const inputStyle = computed(() => {
19
26
  const x = Math.min(props.position.x, window.innerWidth - 380);
20
27
  const y = Math.min(props.position.y + 20, window.innerHeight - 150);
@@ -23,14 +30,68 @@ const inputStyle = computed(() => {
23
30
  top: `${Math.max(10, y)}px`
24
31
  };
25
32
  });
26
- function onAdd() {
27
- const text = comment.value.trim();
28
- if (!text)
33
+ function autoResize() {
34
+ const el = inputEl.value;
35
+ if (!el)
36
+ return;
37
+ el.style.height = "auto";
38
+ el.style.height = `${el.scrollHeight}px`;
39
+ }
40
+ function getComment() {
41
+ const el = inputEl.value;
42
+ if (!el)
43
+ return "";
44
+ return serializeMentions(el);
45
+ }
46
+ function onInput() {
47
+ commentText.value = getComment();
48
+ autoResize();
49
+ mention.checkForTrigger();
50
+ }
51
+ function onKeyDown(e) {
52
+ if (mention.onKeyDown(e))
29
53
  return;
30
- emit("add", text);
54
+ if (e.key === "Enter" && !e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey) {
55
+ e.preventDefault();
56
+ onAdd();
57
+ } else if (e.key === "Escape") {
58
+ if (mention.isOpen.value) {
59
+ e.preventDefault();
60
+ mention.close();
61
+ } else {
62
+ emit("cancel");
63
+ }
64
+ }
65
+ }
66
+ function onAdd() {
67
+ emit("add", getComment().trim());
68
+ }
69
+ function onPaste(e) {
70
+ e.preventDefault();
71
+ const text = e.clipboardData?.getData("text/plain") || "";
72
+ document.execCommand("insertText", false, text);
73
+ }
74
+ function onSelectCandidate(candidate) {
75
+ mention.selectCandidate(candidate);
31
76
  }
32
77
  onMounted(() => {
33
- inputEl.value?.focus();
78
+ const el = inputEl.value;
79
+ if (!el)
80
+ return;
81
+ if (props.initialComment) {
82
+ const html = hydrateMentions(props.initialComment, safeCandidates.value);
83
+ el.innerHTML = html;
84
+ }
85
+ el.focus();
86
+ const sel = window.getSelection();
87
+ if (sel && el.childNodes.length > 0) {
88
+ const range = document.createRange();
89
+ range.selectNodeContents(el);
90
+ range.collapse(false);
91
+ sel.removeAllRanges();
92
+ sel.addRange(range);
93
+ }
94
+ autoResize();
34
95
  });
35
96
  </script>
36
97
 
@@ -66,13 +127,24 @@ onMounted(() => {
66
127
  <ComponentChain :chain="componentChain" variant="light" truncate="leaf" />
67
128
  </div>
68
129
  <span v-else class="__va-input-label">{{ elementName || "Annotation" }}</span>
69
- <input
130
+ <div
70
131
  ref="inputEl"
71
- v-model="comment"
72
- placeholder="Add a comment..."
73
- @keydown.enter="onAdd"
74
- @keydown.escape="$emit('cancel')"
75
- >
132
+ class="__va-input-editable"
133
+ contenteditable="true"
134
+ role="textbox"
135
+ aria-multiline="true"
136
+ data-placeholder="Add a comment..."
137
+ @input="onInput"
138
+ @keydown="onKeyDown"
139
+ @paste="onPaste"
140
+ />
141
+ <MentionDropdown
142
+ :open="mention.isOpen.value"
143
+ :candidates="mention.filteredCandidates.value"
144
+ :active-index="mention.activeIndex.value"
145
+ :position="mention.dropdownPosition.value"
146
+ @select="onSelectCandidate"
147
+ />
76
148
  <div class="__va-input-actions">
77
149
  <button
78
150
  v-if="isEditing"
@@ -86,8 +158,8 @@ onMounted(() => {
86
158
  <VaButton variant="secondary" @click="$emit('cancel')">
87
159
  Cancel
88
160
  </VaButton>
89
- <VaButton :disabled="!comment.trim()" @click="onAdd">
90
- {{ isEditing ? "Save" : "Add" }}
161
+ <VaButton @click="onAdd">
162
+ {{ isEditing ? "Save" : commentText.trim() ? "Add" : "Pin" }}
91
163
  </VaButton>
92
164
  </div>
93
165
  </div>
@@ -1,3 +1,4 @@
1
+ import type { MentionCandidate } from '../utils/mention';
1
2
  type __VLS_Props = {
2
3
  position: {
3
4
  x: number;
@@ -8,6 +9,7 @@ type __VLS_Props = {
8
9
  computedStyles?: Record<string, string>;
9
10
  initialComment?: string;
10
11
  isEditing?: boolean;
12
+ mentionCandidates?: MentionCandidate[];
11
13
  };
12
14
  declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
13
15
  cancel: () => any;
@@ -6,6 +6,7 @@ type __VLS_Props = {
6
6
  isStale?: boolean;
7
7
  isPending?: boolean;
8
8
  isSelection?: boolean;
9
+ hidden?: boolean;
9
10
  };
10
11
  declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
11
12
  click: () => any;
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { computed } from "vue-demi";
2
+ import { computed, onMounted, ref } from "vue-demi";
3
3
  import VaIcon from "./VaIcon.vue";
4
4
  const props = defineProps({
5
5
  number: { type: Number, required: true },
@@ -8,9 +8,16 @@ const props = defineProps({
8
8
  isFixed: { type: Boolean, required: false },
9
9
  isStale: { type: Boolean, required: false },
10
10
  isPending: { type: Boolean, required: false },
11
- isSelection: { type: Boolean, required: false }
11
+ isSelection: { type: Boolean, required: false },
12
+ hidden: { type: Boolean, required: false }
12
13
  });
13
14
  defineEmits(["click"]);
15
+ const entering = ref(true);
16
+ onMounted(() => {
17
+ requestAnimationFrame(() => {
18
+ entering.value = false;
19
+ });
20
+ });
14
21
  const markerStyle = computed(() => ({
15
22
  left: `${props.x}%`,
16
23
  top: `${props.y}px`
@@ -24,7 +31,9 @@ const markerStyle = computed(() => ({
24
31
  '__va-marker--fixed': isFixed,
25
32
  '__va-marker--stale': isStale,
26
33
  '__va-marker--pending': isPending,
27
- '__va-marker--selection': isSelection
34
+ '__va-marker--selection': isSelection,
35
+ '__va-marker--hidden': hidden,
36
+ '__va-marker--entering': entering
28
37
  }"
29
38
  :style="markerStyle"
30
39
  data-agentation-vue
@@ -6,6 +6,7 @@ type __VLS_Props = {
6
6
  isStale?: boolean;
7
7
  isPending?: boolean;
8
8
  isSelection?: boolean;
9
+ hidden?: boolean;
9
10
  };
10
11
  declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
11
12
  click: () => any;
@@ -0,0 +1,16 @@
1
+ import type { MentionCandidate } from '../utils/mention';
2
+ type __VLS_Props = {
3
+ open: boolean;
4
+ candidates: MentionCandidate[];
5
+ activeIndex: number;
6
+ position: {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ };
11
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
12
+ select: (candidate: MentionCandidate) => any;
13
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onSelect?: ((candidate: MentionCandidate) => any) | undefined;
15
+ }>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
16
+ export default _default;
@@ -0,0 +1,41 @@
1
+ <script setup>
2
+ import { computed } from "vue-demi";
3
+ const props = defineProps({
4
+ open: { type: Boolean, required: true },
5
+ candidates: { type: Array, required: true },
6
+ activeIndex: { type: Number, required: true },
7
+ position: { type: Object, required: true }
8
+ });
9
+ defineEmits(["select"]);
10
+ const dropdownStyle = computed(() => {
11
+ if (!props.open)
12
+ return { display: "none" };
13
+ return {
14
+ left: `${props.position.x}px`,
15
+ top: `${props.position.y}px`
16
+ };
17
+ });
18
+ </script>
19
+
20
+ <template>
21
+ <div
22
+ v-show="open && candidates.length > 0"
23
+ class="__va-mention-dropdown"
24
+ :style="dropdownStyle"
25
+ role="listbox"
26
+ data-agentation-vue
27
+ >
28
+ <div
29
+ v-for="(candidate, i) in candidates"
30
+ :key="candidate.id"
31
+ class="__va-mention-option"
32
+ :class="{ '__va-mention-option--active': i === activeIndex }"
33
+ role="option"
34
+ :aria-selected="i === activeIndex"
35
+ @mousedown.prevent="$emit('select', candidate)"
36
+ >
37
+ <span class="__va-mention-option-number">{{ candidate.displayNumber }}</span>
38
+ <span class="__va-mention-option-preview">{{ candidate.commentPreview }}</span>
39
+ </div>
40
+ </div>
41
+ </template>
@@ -0,0 +1,16 @@
1
+ import type { MentionCandidate } from '../utils/mention';
2
+ type __VLS_Props = {
3
+ open: boolean;
4
+ candidates: MentionCandidate[];
5
+ activeIndex: number;
6
+ position: {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ };
11
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
12
+ select: (candidate: MentionCandidate) => any;
13
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onSelect?: ((candidate: MentionCandidate) => any) | undefined;
15
+ }>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
16
+ export default _default;
@@ -1,5 +1,6 @@
1
1
  <script setup>
2
2
  import { computed, toRef } from "vue-demi";
3
+ import { VA_VERSION } from "../constants.mjs";
3
4
  import { vaTooltipDirective } from "../directives/vaTooltip.mjs";
4
5
  import VaIcon from "./VaIcon.vue";
5
6
  import VaToggle from "./VaToggle.vue";
@@ -36,6 +37,7 @@ function toggleTheme() {
36
37
  <template>
37
38
  <div class="__va-settings" data-agentation-vue @click.stop>
38
39
  <div class="__va-settings-top">
40
+ <span class="__va-settings-title">Agentation vue <span class="__va-settings-version">v{{ VA_VERSION }}</span></span>
39
41
  <button v-va-tooltip="'Toggle theme'" type="button" class="__va-theme-toggle" @click="toggleTheme">
40
42
  <VaIcon :name="themeIcon" />
41
43
  </button>
@@ -82,10 +84,10 @@ function toggleTheme() {
82
84
  <div class="__va-settings-divider" />
83
85
 
84
86
  <div class="__va-settings-row">
85
- <span class="__va-settings-label">Clear on copy/send</span>
87
+ <span class="__va-settings-label">Clear After Copy</span>
86
88
  <VaToggle
87
89
  :model-value="settings.clearAfterCopy"
88
- aria-label="Clear on copy/send"
90
+ aria-label="Clear After Copy"
89
91
  @update:model-value="update('clearAfterCopy', $event)"
90
92
  />
91
93
  </div>
@@ -123,7 +125,28 @@ function toggleTheme() {
123
125
  {{ isMac ? "\u2325 Option" : "Alt" }}
124
126
  </option>
125
127
  <option value="Shift">
126
- Shift
128
+ Shift
129
+ </option>
130
+ </select>
131
+ </div>
132
+
133
+ <div class="__va-settings-row">
134
+ <span class="__va-settings-label">Peek inspect (hold key)</span>
135
+ <select :value="settings.peekKey" @change="onSelectChange('peekKey', $event)">
136
+ <option value="none">
137
+ Off
138
+ </option>
139
+ <option value="Meta">
140
+ {{ isMac ? "\u2318 Cmd" : "Ctrl" }}
141
+ </option>
142
+ <option value="Alt">
143
+ {{ isMac ? "\u2325 Option" : "Alt" }}
144
+ </option>
145
+ <option value="Shift">
146
+ ⇧ Shift
147
+ </option>
148
+ <option value="Control">
149
+ {{ isMac ? "\u2303 Control" : "Ctrl" }}
127
150
  </option>
128
151
  </select>
129
152
  </div>
@@ -138,12 +138,10 @@ function schedulePositionUpdate() {
138
138
  function onDocumentPointerDown(e) {
139
139
  if (!props.open)
140
140
  return;
141
- const target = e.target;
142
- if (!target)
141
+ const path = e.composedPath();
142
+ if (panelEl.value && path.includes(panelEl.value))
143
143
  return;
144
- if (panelEl.value?.contains(target))
145
- return;
146
- if (props.anchorEl?.contains(target))
144
+ if (props.anchorEl && path.includes(props.anchorEl))
147
145
  return;
148
146
  emit("close");
149
147
  }
@@ -4,6 +4,7 @@ declare function addAnnotation(annotation: Omit<Annotation, 'id' | 'timestamp'>)
4
4
  declare function removeAnnotation(id: string): Annotation | undefined;
5
5
  declare function updateAnnotation(id: string, updates: Partial<Annotation>): Annotation | undefined;
6
6
  declare function clearAnnotations(): Annotation[];
7
+ declare function restoreAnnotations(items: Annotation[]): void;
7
8
  export declare function setAnnotationStorage(adapter: StorageAdapter): void;
8
9
  export declare function resetAnnotationStorage(): void;
9
10
  export declare function useAnnotations(initialUrl?: string): {
@@ -102,6 +103,7 @@ export declare function useAnnotations(initialUrl?: string): {
102
103
  removeAnnotation: typeof removeAnnotation;
103
104
  updateAnnotation: typeof updateAnnotation;
104
105
  clearAnnotations: typeof clearAnnotations;
106
+ restoreAnnotations: typeof restoreAnnotations;
105
107
  setScopeUrl: typeof setScopeUrl;
106
108
  };
107
109
  export {};
@@ -110,6 +110,11 @@ function clearAnnotations() {
110
110
  save();
111
111
  return cleared;
112
112
  }
113
+ function restoreAnnotations(items) {
114
+ annotations.value.push(...items);
115
+ counter = getCounterSeed(annotations.value);
116
+ save();
117
+ }
113
118
  setScopeUrl(scopedUrl);
114
119
  export function setAnnotationStorage(adapter) {
115
120
  annotationStorage = adapter;
@@ -121,5 +126,5 @@ export function resetAnnotationStorage() {
121
126
  }
122
127
  export function useAnnotations(initialUrl = getCurrentUrl()) {
123
128
  setScopeUrl(initialUrl);
124
- return { annotations, addAnnotation, removeAnnotation, updateAnnotation, clearAnnotations, setScopeUrl };
129
+ return { annotations, addAnnotation, removeAnnotation, updateAnnotation, clearAnnotations, restoreAnnotations, setScopeUrl };
125
130
  }
@@ -50,6 +50,7 @@ export function useKeyboardShortcuts(options) {
50
50
  let lastActivationKeyUpTime = 0;
51
51
  let listenerAttached = false;
52
52
  let mergedKeymap = { ...DEFAULT_KEYMAP, ...options.config.value.keymap };
53
+ const suppressedKeyUps = /* @__PURE__ */ new Set();
53
54
  watch(options.config, (cfg2) => {
54
55
  mergedKeymap = { ...DEFAULT_KEYMAP, ...cfg2.keymap };
55
56
  });
@@ -129,9 +130,15 @@ export function useKeyboardShortcuts(options) {
129
130
  break;
130
131
  }
131
132
  }
132
- function consume(e) {
133
+ function normalizeKey(key) {
134
+ return key.length === 1 ? key.toLowerCase() : key;
135
+ }
136
+ function consume(e, suppressKeyUp = false) {
133
137
  e.preventDefault();
138
+ e.stopImmediatePropagation();
134
139
  e.stopPropagation();
140
+ if (suppressKeyUp)
141
+ suppressedKeyUps.add(normalizeKey(e.key));
135
142
  }
136
143
  function onKeyDown(e) {
137
144
  if (e.repeat)
@@ -145,14 +152,14 @@ export function useKeyboardShortcuts(options) {
145
152
  }
146
153
  if (scope === "settings") {
147
154
  if (e.key === "Escape") {
148
- consume(e);
155
+ consume(e, true);
149
156
  actions.closeSettings();
150
157
  }
151
158
  return;
152
159
  }
153
160
  if (scope === "input") {
154
161
  if (e.key === "Escape") {
155
- consume(e);
162
+ consume(e, true);
156
163
  actions.inputCancel();
157
164
  }
158
165
  return;
@@ -167,11 +174,17 @@ export function useKeyboardShortcuts(options) {
167
174
  if (!action)
168
175
  return;
169
176
  if (cfg().priorityWhenOpen) {
170
- consume(e);
177
+ consume(e, true);
171
178
  }
172
179
  executeAction(action);
173
180
  }
174
181
  function onKeyUp(e) {
182
+ const normalizedKey = normalizeKey(e.key);
183
+ if (suppressedKeyUps.has(normalizedKey)) {
184
+ suppressedKeyUps.delete(normalizedKey);
185
+ consume(e);
186
+ return;
187
+ }
175
188
  const { doubleTap } = cfg();
176
189
  if (!doubleTap.enabled)
177
190
  return;
@@ -198,13 +211,14 @@ export function useKeyboardShortcuts(options) {
198
211
  }
199
212
  function onBlurOrVisibility() {
200
213
  lastActivationKeyUpTime = 0;
214
+ suppressedKeyUps.clear();
201
215
  }
202
216
  function attach() {
203
217
  if (listenerAttached)
204
218
  return;
205
219
  listenerAttached = true;
206
- document.addEventListener("keydown", onKeyDown, true);
207
- document.addEventListener("keyup", onKeyUp, true);
220
+ window.addEventListener("keydown", onKeyDown, true);
221
+ window.addEventListener("keyup", onKeyUp, true);
208
222
  window.addEventListener("blur", onBlurOrVisibility);
209
223
  document.addEventListener("visibilitychange", onBlurOrVisibility);
210
224
  }
@@ -212,8 +226,8 @@ export function useKeyboardShortcuts(options) {
212
226
  if (!listenerAttached)
213
227
  return;
214
228
  listenerAttached = false;
215
- document.removeEventListener("keydown", onKeyDown, true);
216
- document.removeEventListener("keyup", onKeyUp, true);
229
+ window.removeEventListener("keydown", onKeyDown, true);
230
+ window.removeEventListener("keyup", onKeyUp, true);
217
231
  window.removeEventListener("blur", onBlurOrVisibility);
218
232
  document.removeEventListener("visibilitychange", onBlurOrVisibility);
219
233
  }
@@ -0,0 +1,21 @@
1
+ import type { Ref } from 'vue-demi';
2
+ import type { MentionCandidate } from '../utils/mention';
3
+ export declare function useMentionDropdown(inputEl: Ref<HTMLElement | null>, candidates: Ref<MentionCandidate[]>): {
4
+ isOpen: Ref<boolean, boolean>;
5
+ filteredCandidates: import("vue-demi").ComputedRef<MentionCandidate[]>;
6
+ activeIndex: Ref<number, number>;
7
+ dropdownPosition: Ref<{
8
+ x: number;
9
+ y: number;
10
+ }, {
11
+ x: number;
12
+ y: number;
13
+ } | {
14
+ x: number;
15
+ y: number;
16
+ }>;
17
+ checkForTrigger: () => void;
18
+ selectCandidate: (candidate: MentionCandidate) => void;
19
+ onKeyDown: (e: KeyboardEvent) => boolean;
20
+ close: () => void;
21
+ };