mentionize 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Mentionize
2
2
 
3
- A React library for building mention inputs with support for multiple triggers, async search, and full customization. It provides a transparent textarea overlaid on a highlighted div to display mentions, and a dropdown for suggestions. With zero dependencies.
3
+ A React library for building mention inputs with support for multiple triggers, async search, and full customization. It provides a transparent textarea overlaid on a highlighted div to display mentions, and a dropdown for suggestions. With zero dependencies other than React.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```bash
8
+ npm install react
9
+ npm install react-dom
10
+
8
11
  npm install mentionize
9
12
  ```
10
13
 
@@ -61,8 +64,10 @@ Defines how a trigger character activates suggestions and how mentions are seria
61
64
  | `options?` | `T[]` | Static options array (client-side filtering) |
62
65
  | `onSearch?` | `(query: string, page: number) => Promise<{ items: T[]; hasMore: boolean }>` | Async search with pagination |
63
66
  | `renderOption?` | `(item: T, highlighted: boolean) => ReactNode` | Custom option rendering |
64
- | `renderMention?` | `(displayText: string) => ReactNode` | Custom mention highlight rendering |
65
- | `mentionClassName?` | `string` | CSS class for highlighted mentions in the overlay |
67
+ | `optionClassName?` | `string \| ((item: T) => string)` | CSS class for dropdown options, or a function for conditional styling per item |
68
+ | `renderMention?` | `(displayText: string, item?: unknown) => ReactNode` | Custom mention highlight rendering |
69
+ | `mentionClassName?` | `string \| ((mention: MentionItemData) => string)` | CSS class for highlighted mentions, or a function for conditional styling |
70
+ | `onSelect?` | `(item: T) => Promise<string \| null> \| string \| null` | Action trigger: runs instead of inserting a mention. Returns text to insert or null to cancel. |
66
71
 
67
72
  ### `MentionInputProps`
68
73
 
@@ -81,7 +86,10 @@ Defines how a trigger character activates suggestions and how mentions are seria
81
86
  | `highlighterClassName?` | `string` | Highlighter overlay className |
82
87
  | `dropdownClassName?` | `string` | Dropdown className |
83
88
  | `dropdownWidth?` | `number` | Dropdown width in pixels (default: 250) |
89
+ | `loadingText?` | `string` | Text shown while loading async results (default: `"Loading..."`) |
84
90
  | `renderDropdown?` | `(props: DropdownRenderProps) => ReactNode` | Full custom dropdown rendering |
91
+ | `aria-label?` | `string` | Accessible label for the textarea |
92
+ | `aria-describedby?` | `string` | ID of an element describing the textarea |
85
93
 
86
94
  ## Multiple Triggers
87
95
 
@@ -125,13 +133,14 @@ const engine = useMentionEngine({
125
133
  onChange: setValue,
126
134
  });
127
135
 
128
- // engine.visible - display text
129
- // engine.mentions - active mentions with positions
130
- // engine.activeTrigger - currently active trigger (or null)
131
- // engine.filteredOptions - filtered suggestions
136
+ // engine.visible - display text
137
+ // engine.mentions - active mentions with positions
138
+ // engine.activeTrigger - currently active trigger (or null)
139
+ // engine.filteredOptions - filtered suggestions
132
140
  // engine.handleTextChange(text, caretPos)
133
141
  // engine.handleKeyDown(event, textarea)
134
142
  // engine.selectOption(item, textarea)
143
+ // engine.getItemForMention(triggerChar, key) - look up cached item for a mention
135
144
  ```
136
145
 
137
146
  ## Styling
@@ -148,6 +157,69 @@ Mentionize uses a transparent textarea overlaid on a highlighted div. Apply styl
148
157
  />
149
158
  ```
150
159
 
160
+ ### Conditional Mention Styling
161
+
162
+ Use a function for `mentionClassName` to style mentions dynamically based on the underlying item data:
163
+
164
+ ```tsx
165
+ import type { MentionItemData } from "mentionize";
166
+
167
+ const userTrigger: MentionTrigger<User> = {
168
+ trigger: "@",
169
+ mentionClassName: (mention: MentionItemData) => {
170
+ const user = mention.item as User;
171
+ switch (user?.role) {
172
+ case "Engineer": return "mention-engineer";
173
+ case "Designer": return "mention-designer";
174
+ case "PM": return "mention-pm";
175
+ default: return "mention-user";
176
+ }
177
+ },
178
+ // Apply the same conditional styling to dropdown options
179
+ optionClassName: (user) => {
180
+ switch (user.role) {
181
+ case "Engineer": return "mention-engineer";
182
+ case "Designer": return "mention-designer";
183
+ case "PM": return "mention-pm";
184
+ default: return "mention-user";
185
+ }
186
+ },
187
+ // ...other config
188
+ };
189
+ ```
190
+
191
+ The `MentionItemData` object contains `key`, `displayText`, `trigger`, and `item` (the original cached item). Use `optionClassName` (string or function receiving the item directly) to apply matching styles to dropdown options.
192
+
193
+ ### Action Triggers
194
+
195
+ Use `onSelect` to create triggers that run an action instead of inserting a mention. The callback receives the selected item and returns a string to insert as plain text, or `null` to cancel:
196
+
197
+ ```tsx
198
+ const commandTrigger: MentionTrigger<Command> = {
199
+ trigger: "/",
200
+ displayText: (cmd) => cmd.label,
201
+ // serialize/pattern/parseMatch still needed for the dropdown
202
+ serialize: (cmd) => `/[${cmd.label}](cmd:${cmd.id})`,
203
+ pattern: /\/\[([^\]]+)\]\(cmd:([^)]+)\)/g,
204
+ parseMatch: (match) => ({ displayText: match[1]!, key: match[2]! }),
205
+ options: [
206
+ { id: "date", label: "Insert Date" },
207
+ { id: "emoji", label: "Pick Emoji" },
208
+ ],
209
+ onSelect: async (cmd) => {
210
+ if (cmd.id === "date") return new Date().toLocaleDateString();
211
+ if (cmd.id === "emoji") {
212
+ // simulate async work
213
+ await new Promise((r) => setTimeout(r, 500));
214
+ return "🎉";
215
+ }
216
+ return null; // cancel — nothing inserted
217
+ },
218
+ };
219
+ ```
220
+
221
+ When `onSelect` is defined, selecting an option calls the function instead of inserting a mention. The trigger text and query are replaced by the returned string.
222
+
151
223
  Per-trigger mention highlights can be styled via `mentionClassName`:
152
224
 
153
225
  ```tsx
@@ -8,6 +8,7 @@ interface MentionDropdownProps {
8
8
  onSelect: (item: unknown) => void;
9
9
  onLoadMore?: () => void;
10
10
  loading: boolean;
11
+ loadingText?: string;
11
12
  position: CaretPosition;
12
13
  width: number;
13
14
  className?: string;
@@ -5,6 +5,7 @@ interface MentionHighlighterProps {
5
5
  mentions: ActiveMention[];
6
6
  triggers: MentionTrigger<any>[];
7
7
  textareaRef: React.RefObject<HTMLTextAreaElement | null>;
8
+ getItemForMention?: (triggerChar: string, key: string) => unknown;
8
9
  className?: string;
9
10
  style?: React.CSSProperties;
10
11
  }
@@ -3,4 +3,4 @@ export { MentionHighlighter } from "./MentionHighlighter.tsx";
3
3
  export { MentionDropdown } from "./MentionDropdown.tsx";
4
4
  export { useMentionEngine } from "./useMentionEngine.ts";
5
5
  export { useCaretPosition } from "./useCaretPosition.ts";
6
- export type { MentionTrigger, MentionInputProps, ActiveMention, DropdownRenderProps, CaretPosition, } from "./types.ts";
6
+ export type { MentionTrigger, MentionItemData, MentionInputProps, ActiveMention, DropdownRenderProps, CaretPosition, } from "./types.ts";
package/dist/cjs/index.js CHANGED
@@ -64,6 +64,7 @@ var MentionDropdown = ({
64
64
  onSelect,
65
65
  onLoadMore,
66
66
  loading,
67
+ loadingText,
67
68
  position,
68
69
  width,
69
70
  className
@@ -118,10 +119,12 @@ var MentionDropdown = ({
118
119
  children: [
119
120
  items.map((item, i) => {
120
121
  const isHighlighted = i === highlightedIndex;
122
+ const optCls = typeof trigger.optionClassName === "function" ? trigger.optionClassName(item) : trigger.optionClassName;
121
123
  if (trigger.renderOption) {
122
124
  return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
123
125
  role: "option",
124
126
  "aria-selected": isHighlighted,
127
+ className: optCls,
125
128
  "data-mentionize-option-index": i,
126
129
  "data-mentionize-option-highlighted": isHighlighted || undefined,
127
130
  onMouseEnter: () => onHighlight(i),
@@ -132,6 +135,7 @@ var MentionDropdown = ({
132
135
  return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
133
136
  role: "option",
134
137
  "aria-selected": isHighlighted,
138
+ className: optCls,
135
139
  "data-mentionize-option-index": i,
136
140
  "data-mentionize-option": "",
137
141
  "data-mentionize-option-highlighted": isHighlighted || undefined,
@@ -142,7 +146,7 @@ var MentionDropdown = ({
142
146
  }),
143
147
  loading && /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
144
148
  "data-mentionize-loading": "",
145
- children: "Loading..."
149
+ children: loadingText ?? "Loading..."
146
150
  }, undefined, false, undefined, this),
147
151
  onLoadMore && !loading && /* @__PURE__ */ jsx_dev_runtime.jsxDEV("div", {
148
152
  ref: sentinelRef,
@@ -172,6 +176,7 @@ var MentionHighlighter = ({
172
176
  mentions,
173
177
  triggers,
174
178
  textareaRef,
179
+ getItemForMention,
175
180
  className,
176
181
  style
177
182
  }) => {
@@ -192,9 +197,9 @@ var MentionHighlighter = ({
192
197
  const sorted = mentions.slice().sort((a, b) => a.start - b.start);
193
198
  if (!sorted.length)
194
199
  return textToNodes(visible);
195
- const classMap = new Map;
200
+ const triggerMap = new Map;
196
201
  for (const t of triggers) {
197
- classMap.set(t.trigger, t.mentionClassName ?? "mentionize-mention");
202
+ triggerMap.set(t.trigger, t);
198
203
  }
199
204
  const nodes = [];
200
205
  let last = 0;
@@ -204,7 +209,21 @@ var MentionHighlighter = ({
204
209
  nodes.push(...textToNodes(visible.slice(last, m.start)));
205
210
  }
206
211
  const mentionText = visible.slice(m.start, m.end);
207
- const cls = classMap.get(m.trigger) ?? "mentionize-mention";
212
+ const t = triggerMap.get(m.trigger);
213
+ let cls = "mentionize-mention";
214
+ if (t) {
215
+ if (typeof t.mentionClassName === "function") {
216
+ const item = getItemForMention?.(m.trigger, m.key) ?? null;
217
+ cls = t.mentionClassName({
218
+ key: m.key,
219
+ displayText: m.displayText,
220
+ trigger: m.trigger,
221
+ item
222
+ });
223
+ } else if (t.mentionClassName) {
224
+ cls = t.mentionClassName;
225
+ }
226
+ }
208
227
  nodes.push(import_react2.default.createElement("span", {
209
228
  key: `mention-${i}`,
210
229
  className: cls,
@@ -217,7 +236,7 @@ var MentionHighlighter = ({
217
236
  nodes.push(...textToNodes(visible.slice(last)));
218
237
  }
219
238
  return nodes;
220
- }, [visible, mentions, triggers]);
239
+ }, [visible, mentions, triggers, getItemForMention]);
221
240
  import_react2.useLayoutEffect(() => {
222
241
  const el = ref.current;
223
242
  if (!el)
@@ -618,10 +637,41 @@ function useMentionEngine(options) {
618
637
  setActiveTrigger(null);
619
638
  }
620
639
  }, [detectActiveTrigger, emitSync]);
640
+ const getItemForMention = import_react4.useCallback((triggerChar, key) => {
641
+ const cache = getCache(triggerChar);
642
+ return cache.get(key) ?? null;
643
+ }, []);
621
644
  const selectOption = import_react4.useCallback((item, textarea) => {
622
645
  if (!activeTrigger)
623
646
  return;
624
647
  const t = activeTrigger.trigger;
648
+ if (t.onSelect) {
649
+ const before2 = visible.slice(0, activeTrigger.startPos);
650
+ const after2 = visible.slice(textarea.selectionStart);
651
+ const savedStartPos = activeTrigger.startPos;
652
+ setActiveTrigger(null);
653
+ const result = t.onSelect(item);
654
+ const applyResult = (value) => {
655
+ if (value !== null) {
656
+ const newVis2 = before2 + value + after2;
657
+ const pos2 = savedStartPos + value.length;
658
+ caretPosRef.current = pos2;
659
+ setVisible(newVis2);
660
+ emitSync(newVis2);
661
+ } else {
662
+ const newVis2 = before2 + after2;
663
+ caretPosRef.current = savedStartPos;
664
+ setVisible(newVis2);
665
+ emitSync(newVis2);
666
+ }
667
+ };
668
+ if (result instanceof Promise) {
669
+ result.then(applyResult);
670
+ } else {
671
+ applyResult(result);
672
+ }
673
+ return;
674
+ }
625
675
  const cache = getCache(t.trigger);
626
676
  const key = getItemKey(t, item);
627
677
  cache.set(key, item);
@@ -699,7 +749,8 @@ function useMentionEngine(options) {
699
749
  loadMore,
700
750
  rawToVisible,
701
751
  visibleToRaw,
702
- caretPosRef
752
+ caretPosRef,
753
+ getItemForMention
703
754
  };
704
755
  }
705
756
  function getItemKey(trigger, item) {
@@ -739,6 +790,7 @@ var MentionInput = import_react5.forwardRef(({
739
790
  highlighterClassName,
740
791
  dropdownClassName,
741
792
  dropdownWidth = 250,
793
+ loadingText,
742
794
  renderDropdown,
743
795
  "aria-label": ariaLabel,
744
796
  "aria-describedby": ariaDescribedBy
@@ -811,6 +863,7 @@ var MentionInput = import_react5.forwardRef(({
811
863
  mentions: engine.mentions,
812
864
  triggers,
813
865
  textareaRef,
866
+ getItemForMention: engine.getItemForMention,
814
867
  className: highlighterClassName,
815
868
  style: SHARED_STYLE
816
869
  }, undefined, false, undefined, this),
@@ -868,6 +921,7 @@ var MentionInput = import_react5.forwardRef(({
868
921
  onSelect: handleSelect,
869
922
  onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,
870
923
  loading: engine.searchLoading,
924
+ loadingText,
871
925
  position: dropdownPos,
872
926
  width: dropdownWidth,
873
927
  className: dropdownClassName
@@ -877,5 +931,5 @@ var MentionInput = import_react5.forwardRef(({
877
931
  });
878
932
  MentionInput.displayName = "MentionInput";
879
933
 
880
- //# debugId=2D34F896A558FE4664756E2164756E21
934
+ //# debugId=E1E2DCC63463DE3264756E2164756E21
881
935
  //# sourceMappingURL=index.js.map
@@ -2,14 +2,14 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/MentionInput.tsx", "../../src/MentionDropdown.tsx", "../../src/MentionHighlighter.tsx", "../../src/useCaretPosition.ts", "../../src/useMentionEngine.ts", "../../src/utils.ts"],
4
4
  "sourcesContent": [
5
- "import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { MentionDropdown } from \"./MentionDropdown.tsx\";\nimport { MentionHighlighter } from \"./MentionHighlighter.tsx\";\nimport type { CaretPosition, MentionInputProps } from \"./types.ts\";\nimport { useCaretPosition } from \"./useCaretPosition.ts\";\nimport { useMentionEngine } from \"./useMentionEngine.ts\";\n\nconst SHARED_STYLE: React.CSSProperties = {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"anywhere\",\n wordBreak: \"break-word\",\n padding: \"0.5rem 0.75rem\",\n fontFamily: \"inherit\",\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n letterSpacing: \"normal\",\n boxSizing: \"border-box\",\n};\n\nexport const MentionInput = forwardRef<HTMLTextAreaElement, MentionInputProps>(\n (\n {\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n placeholder,\n disabled,\n rows = 4,\n className,\n inputClassName,\n highlighterClassName,\n dropdownClassName,\n dropdownWidth = 250,\n renderDropdown,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n },\n ref\n ) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n useImperativeHandle(ref, () => textareaRef.current!);\n\n const engine = useMentionEngine({\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n });\n\n // Restore caret position after render, then clear so we don't\n // fight the browser on subsequent renders (like arrow-key navigation)\n useLayoutEffect(() => {\n const pos = engine.caretPosRef.current;\n const ta = textareaRef.current;\n if (pos !== null && ta && document.activeElement === ta) {\n ta.setSelectionRange(pos, pos);\n engine.caretPosRef.current = null;\n }\n });\n\n const { mirrorRef, getCaretPosition } = useCaretPosition(dropdownWidth);\n const [dropdownPos, setDropdownPos] = useState<CaretPosition | null>(null);\n\n // Update dropdown position when active trigger changes\n useEffect(() => {\n if (engine.activeTrigger && textareaRef.current) {\n requestAnimationFrame(() => {\n const pos = getCaretPosition(textareaRef.current!);\n if (pos) setDropdownPos(pos);\n });\n } else {\n setDropdownPos(null);\n }\n }, [engine.activeTrigger, engine.visible, getCaretPosition]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n engine.handleTextChange(e.target.value, e.target.selectionStart);\n },\n [engine.handleTextChange]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (textareaRef.current) {\n engine.handleKeyDown(e, textareaRef.current);\n }\n },\n [engine.handleKeyDown]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const ta = textareaRef.current;\n if (!ta) return;\n const txt = e.clipboardData.getData(\"text\");\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const newText =\n engine.visible.slice(0, start) + txt + engine.visible.slice(end);\n e.preventDefault();\n engine.handleTextChange(newText, start + txt.length);\n },\n [engine.visible, engine.handleTextChange]\n );\n\n const handleBlur = useCallback(() => {\n // delay allows dropdown click to fire first\n setTimeout(() => engine.closeSuggestions(), 150);\n }, [engine.closeSuggestions]);\n\n const handleSelect = useCallback(\n (item: unknown) => {\n if (textareaRef.current) {\n engine.selectOption(item, textareaRef.current);\n }\n },\n [engine.selectOption]\n );\n\n const showDropdown = engine.activeTrigger !== null && dropdownPos !== null;\n\n return (\n <div\n className={className}\n style={{ position: \"relative\" }}\n data-mentionize-container=\"\"\n >\n <MentionHighlighter\n visible={engine.visible}\n mentions={engine.mentions}\n triggers={triggers}\n textareaRef={textareaRef}\n className={highlighterClassName}\n style={SHARED_STYLE}\n />\n\n <textarea\n ref={textareaRef}\n value={engine.visible}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={handleBlur}\n rows={rows}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n aria-autocomplete=\"list\"\n aria-expanded={showDropdown}\n className={inputClassName}\n style={{\n ...SHARED_STYLE,\n position: \"relative\",\n width: \"100%\",\n resize: \"vertical\",\n background: \"transparent\",\n color: \"transparent\",\n caretColor: \"CanvasText\",\n zIndex: 10,\n }}\n data-mentionize-input=\"\"\n />\n\n {/* Caret mirror div */}\n <div\n ref={mirrorRef}\n aria-hidden\n style={{\n position: \"absolute\",\n top: 0,\n left: -9999,\n visibility: \"hidden\",\n ...SHARED_STYLE,\n }}\n data-mentionize-mirror=\"\"\n />\n\n {showDropdown && engine.activeTrigger && (\n renderDropdown ? (\n renderDropdown({\n items: engine.filteredOptions,\n highlightedIndex: engine.highlightIndex,\n onSelect: handleSelect,\n onHighlight: engine.setHighlightIndex,\n loading: engine.searchLoading,\n onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,\n })\n ) : (\n <MentionDropdown\n items={engine.filteredOptions}\n trigger={engine.activeTrigger.trigger}\n highlightedIndex={engine.highlightIndex}\n onHighlight={engine.setHighlightIndex}\n onSelect={handleSelect}\n onLoadMore={engine.searchHasMore ? engine.loadMore : undefined}\n loading={engine.searchLoading}\n position={dropdownPos}\n width={dropdownWidth}\n className={dropdownClassName}\n />\n )\n )}\n </div>\n );\n }\n);\n\nMentionInput.displayName = \"MentionInput\";\n",
6
- "import React, { useCallback, useEffect, useRef } from \"react\";\nimport type { CaretPosition, MentionTrigger } from \"./types.ts\";\n\ninterface MentionDropdownProps {\n items: unknown[];\n trigger: MentionTrigger<any>;\n highlightedIndex: number;\n onHighlight: (index: number) => void;\n onSelect: (item: unknown) => void;\n onLoadMore?: () => void;\n loading: boolean;\n position: CaretPosition;\n width: number;\n className?: string;\n}\n\nexport const MentionDropdown: React.FC<MentionDropdownProps> = ({\n items,\n trigger,\n highlightedIndex,\n onHighlight,\n onSelect,\n onLoadMore,\n loading,\n position,\n width,\n className,\n}) => {\n const listRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // IntersectionObserver for infinite scroll\n useEffect(() => {\n if (!onLoadMore || !sentinelRef.current) return;\n const sentinel = sentinelRef.current;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n onLoadMore();\n }\n },\n { root: listRef.current, threshold: 0.1 }\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [onLoadMore]);\n\n // Ensure highlighted item is visible\n useEffect(() => {\n const container = listRef.current;\n if (!container) return;\n const highlighted = container.querySelector(\n `[data-mentionize-option-index=\"${highlightedIndex}\"]`\n ) as HTMLElement | null;\n if (highlighted) {\n highlighted.scrollIntoView({ block: \"nearest\" });\n }\n }, [highlightedIndex]);\n\n // flip above if near bottom of viewport\n const maxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - position.top - gap;\n const flipAbove = spaceBelow < maxHeight && position.top > maxHeight;\n\n const style: React.CSSProperties = {\n position: \"fixed\",\n width,\n maxHeight,\n overflowY: \"auto\",\n zIndex: 50,\n ...(flipAbove\n ? { bottom: window.innerHeight - position.top + gap, left: position.left }\n : { top: position.top + gap, left: position.left }),\n };\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault(); // prevent blur of input\n }, []);\n\n if (!items.length && !loading) return null;\n\n return (\n <div\n ref={listRef}\n role=\"listbox\"\n className={className}\n style={style}\n data-mentionize-dropdown=\"\"\n onMouseDown={handleMouseDown}\n >\n {items.map((item, i) => {\n const isHighlighted = i === highlightedIndex;\n\n if (trigger.renderOption) {\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n data-mentionize-option-index={i}\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.renderOption(item, isHighlighted)}\n </div>\n );\n }\n\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n data-mentionize-option-index={i}\n data-mentionize-option=\"\"\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.displayText(item)}\n </div>\n );\n })}\n {loading && (\n <div data-mentionize-loading=\"\">Loading...</div>\n )}\n {onLoadMore && !loading && (\n <div ref={sentinelRef} style={{ height: 1 }} aria-hidden />\n )}\n </div>\n );\n};\n",
7
- "import React, { useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\n\ninterface MentionHighlighterProps {\n visible: string;\n mentions: ActiveMention[];\n triggers: MentionTrigger<any>[];\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Split a string so that newlines become <br/> elements */\nfunction textToNodes(text: string): React.ReactNode[] {\n const parts = text.split(\"\\n\");\n const nodes: React.ReactNode[] = [];\n for (let i = 0; i < parts.length; i++) {\n if (i > 0) nodes.push(React.createElement(\"br\", { key: `br-${i}` }));\n if (parts[i]) nodes.push(parts[i]);\n }\n return nodes;\n}\n\nexport const MentionHighlighter: React.FC<MentionHighlighterProps> = ({\n visible,\n mentions,\n triggers,\n textareaRef,\n className,\n style,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n\n // Sync scroll with textarea\n useEffect(() => {\n const textarea = textareaRef.current;\n const highlighter = ref.current;\n if (!textarea || !highlighter) return;\n\n const onScroll = () => {\n highlighter.scrollTop = textarea.scrollTop;\n highlighter.scrollLeft = textarea.scrollLeft;\n };\n\n textarea.addEventListener(\"scroll\", onScroll);\n return () => textarea.removeEventListener(\"scroll\", onScroll);\n }, [textareaRef]);\n\n const children = useMemo(() => {\n const sorted = mentions.slice().sort((a, b) => a.start - b.start);\n if (!sorted.length) return textToNodes(visible);\n\n const classMap = new Map<string, string>();\n for (const t of triggers) {\n classMap.set(t.trigger, t.mentionClassName ?? \"mentionize-mention\");\n }\n\n const nodes: React.ReactNode[] = [];\n let last = 0;\n for (let i = 0; i < sorted.length; i++) {\n const m = sorted[i]!;\n // Text before this mention\n if (last < m.start) {\n nodes.push(...textToNodes(visible.slice(last, m.start)));\n }\n\n const mentionText = visible.slice(m.start, m.end);\n const cls = classMap.get(m.trigger) ?? \"mentionize-mention\";\n nodes.push(\n React.createElement(\n \"span\",\n {\n key: `mention-${i}`,\n className: cls,\n \"data-mentionize-trigger\": m.trigger,\n \"data-mentionize-key\": m.key,\n },\n mentionText\n )\n );\n last = m.end;\n }\n // after last mention\n if (last < visible.length) {\n nodes.push(...textToNodes(visible.slice(last)));\n }\n return nodes;\n }, [visible, mentions, triggers]);\n\n // After render, neutralize horizontal box-model impact of mention spans\n // so user-applied padding/border/margin don't shift overlay text relative to the textarea.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const spans = el.querySelectorAll<HTMLElement>(\"[data-mentionize-trigger]\");\n for (let i = 0; i < spans.length; i++) {\n const span = spans[i]!;\n // Reset any previous compensation before measuring\n span.style.marginLeft = \"\";\n span.style.marginRight = \"\";\n const cs = getComputedStyle(span);\n const extraLeft =\n parseFloat(cs.paddingLeft) +\n parseFloat(cs.borderLeftWidth) +\n parseFloat(cs.marginLeft);\n const extraRight =\n parseFloat(cs.paddingRight) +\n parseFloat(cs.borderRightWidth) +\n parseFloat(cs.marginRight);\n if (extraLeft) span.style.marginLeft = `${-extraLeft}px`;\n if (extraRight) span.style.marginRight = `${-extraRight}px`;\n }\n });\n\n return React.createElement(\n \"div\",\n {\n ref,\n className,\n style: {\n position: \"absolute\" as const,\n inset: 0,\n pointerEvents: \"none\" as const,\n overflow: \"auto\",\n ...style,\n },\n \"aria-hidden\": true,\n \"data-mentionize-highlighter\": \"\",\n },\n ...children\n );\n};\n",
5
+ "import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { MentionDropdown } from \"./MentionDropdown.tsx\";\nimport { MentionHighlighter } from \"./MentionHighlighter.tsx\";\nimport type { CaretPosition, MentionInputProps } from \"./types.ts\";\nimport { useCaretPosition } from \"./useCaretPosition.ts\";\nimport { useMentionEngine } from \"./useMentionEngine.ts\";\n\nconst SHARED_STYLE: React.CSSProperties = {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"anywhere\",\n wordBreak: \"break-word\",\n padding: \"0.5rem 0.75rem\",\n fontFamily: \"inherit\",\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n letterSpacing: \"normal\",\n boxSizing: \"border-box\",\n};\n\nexport const MentionInput = forwardRef<HTMLTextAreaElement, MentionInputProps>(\n (\n {\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n placeholder,\n disabled,\n rows = 4,\n className,\n inputClassName,\n highlighterClassName,\n dropdownClassName,\n dropdownWidth = 250,\n loadingText,\n renderDropdown,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n },\n ref\n ) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n useImperativeHandle(ref, () => textareaRef.current!);\n\n const engine = useMentionEngine({\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n });\n\n // Restore caret position after render, then clear so we don't\n // fight the browser on subsequent renders (like arrow-key navigation)\n useLayoutEffect(() => {\n const pos = engine.caretPosRef.current;\n const ta = textareaRef.current;\n if (pos !== null && ta && document.activeElement === ta) {\n ta.setSelectionRange(pos, pos);\n engine.caretPosRef.current = null;\n }\n });\n\n const { mirrorRef, getCaretPosition } = useCaretPosition(dropdownWidth);\n const [dropdownPos, setDropdownPos] = useState<CaretPosition | null>(null);\n\n // Update dropdown position when active trigger changes\n useEffect(() => {\n if (engine.activeTrigger && textareaRef.current) {\n requestAnimationFrame(() => {\n const pos = getCaretPosition(textareaRef.current!);\n if (pos) setDropdownPos(pos);\n });\n } else {\n setDropdownPos(null);\n }\n }, [engine.activeTrigger, engine.visible, getCaretPosition]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n engine.handleTextChange(e.target.value, e.target.selectionStart);\n },\n [engine.handleTextChange]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (textareaRef.current) {\n engine.handleKeyDown(e, textareaRef.current);\n }\n },\n [engine.handleKeyDown]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const ta = textareaRef.current;\n if (!ta) return;\n const txt = e.clipboardData.getData(\"text\");\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const newText =\n engine.visible.slice(0, start) + txt + engine.visible.slice(end);\n e.preventDefault();\n engine.handleTextChange(newText, start + txt.length);\n },\n [engine.visible, engine.handleTextChange]\n );\n\n const handleBlur = useCallback(() => {\n // delay allows dropdown click to fire first\n setTimeout(() => engine.closeSuggestions(), 150);\n }, [engine.closeSuggestions]);\n\n const handleSelect = useCallback(\n (item: unknown) => {\n if (textareaRef.current) {\n engine.selectOption(item, textareaRef.current);\n }\n },\n [engine.selectOption]\n );\n\n const showDropdown = engine.activeTrigger !== null && dropdownPos !== null;\n\n return (\n <div\n className={className}\n style={{ position: \"relative\" }}\n data-mentionize-container=\"\"\n >\n <MentionHighlighter\n visible={engine.visible}\n mentions={engine.mentions}\n triggers={triggers}\n textareaRef={textareaRef}\n getItemForMention={engine.getItemForMention}\n className={highlighterClassName}\n style={SHARED_STYLE}\n />\n\n <textarea\n ref={textareaRef}\n value={engine.visible}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={handleBlur}\n rows={rows}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n aria-autocomplete=\"list\"\n aria-expanded={showDropdown}\n className={inputClassName}\n style={{\n ...SHARED_STYLE,\n position: \"relative\",\n width: \"100%\",\n resize: \"vertical\",\n background: \"transparent\",\n color: \"transparent\",\n caretColor: \"CanvasText\",\n zIndex: 10,\n }}\n data-mentionize-input=\"\"\n />\n\n {/* Caret mirror div */}\n <div\n ref={mirrorRef}\n aria-hidden\n style={{\n position: \"absolute\",\n top: 0,\n left: -9999,\n visibility: \"hidden\",\n ...SHARED_STYLE,\n }}\n data-mentionize-mirror=\"\"\n />\n\n {showDropdown && engine.activeTrigger && (\n renderDropdown ? (\n renderDropdown({\n items: engine.filteredOptions,\n highlightedIndex: engine.highlightIndex,\n onSelect: handleSelect,\n onHighlight: engine.setHighlightIndex,\n loading: engine.searchLoading,\n onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,\n })\n ) : (\n <MentionDropdown\n items={engine.filteredOptions}\n trigger={engine.activeTrigger.trigger}\n highlightedIndex={engine.highlightIndex}\n onHighlight={engine.setHighlightIndex}\n onSelect={handleSelect}\n onLoadMore={engine.searchHasMore ? engine.loadMore : undefined}\n loading={engine.searchLoading}\n loadingText={loadingText}\n position={dropdownPos}\n width={dropdownWidth}\n className={dropdownClassName}\n />\n )\n )}\n </div>\n );\n }\n);\n\nMentionInput.displayName = \"MentionInput\";\n",
6
+ "import React, { useCallback, useEffect, useRef } from \"react\";\nimport type { CaretPosition, MentionTrigger } from \"./types.ts\";\n\ninterface MentionDropdownProps {\n items: unknown[];\n trigger: MentionTrigger<any>;\n highlightedIndex: number;\n onHighlight: (index: number) => void;\n onSelect: (item: unknown) => void;\n onLoadMore?: () => void;\n loading: boolean;\n loadingText?: string;\n position: CaretPosition;\n width: number;\n className?: string;\n}\n\nexport const MentionDropdown: React.FC<MentionDropdownProps> = ({\n items,\n trigger,\n highlightedIndex,\n onHighlight,\n onSelect,\n onLoadMore,\n loading,\n loadingText,\n position,\n width,\n className,\n}) => {\n const listRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // IntersectionObserver for infinite scroll\n useEffect(() => {\n if (!onLoadMore || !sentinelRef.current) return;\n const sentinel = sentinelRef.current;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n onLoadMore();\n }\n },\n { root: listRef.current, threshold: 0.1 }\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [onLoadMore]);\n\n // Ensure highlighted item is visible\n useEffect(() => {\n const container = listRef.current;\n if (!container) return;\n const highlighted = container.querySelector(\n `[data-mentionize-option-index=\"${highlightedIndex}\"]`\n ) as HTMLElement | null;\n if (highlighted) {\n highlighted.scrollIntoView({ block: \"nearest\" });\n }\n }, [highlightedIndex]);\n\n // flip above if near bottom of viewport\n const maxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - position.top - gap;\n const flipAbove = spaceBelow < maxHeight && position.top > maxHeight;\n\n const style: React.CSSProperties = {\n position: \"fixed\",\n width,\n maxHeight,\n overflowY: \"auto\",\n zIndex: 50,\n ...(flipAbove\n ? { bottom: window.innerHeight - position.top + gap, left: position.left }\n : { top: position.top + gap, left: position.left }),\n };\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault(); // prevent blur of input\n }, []);\n\n if (!items.length && !loading) return null;\n\n return (\n <div\n ref={listRef}\n role=\"listbox\"\n className={className}\n style={style}\n data-mentionize-dropdown=\"\"\n onMouseDown={handleMouseDown}\n >\n {items.map((item, i) => {\n const isHighlighted = i === highlightedIndex;\n const optCls = typeof trigger.optionClassName === \"function\"\n ? trigger.optionClassName(item)\n : trigger.optionClassName;\n\n if (trigger.renderOption) {\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n className={optCls}\n data-mentionize-option-index={i}\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.renderOption(item, isHighlighted)}\n </div>\n );\n }\n\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n className={optCls}\n data-mentionize-option-index={i}\n data-mentionize-option=\"\"\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.displayText(item)}\n </div>\n );\n })}\n {loading && (\n <div data-mentionize-loading=\"\">{loadingText ?? \"Loading...\"}</div>\n )}\n {onLoadMore && !loading && (\n <div ref={sentinelRef} style={{ height: 1 }} aria-hidden />\n )}\n </div>\n );\n};\n",
7
+ "import React, { useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\n\ninterface MentionHighlighterProps {\n visible: string;\n mentions: ActiveMention[];\n triggers: MentionTrigger<any>[];\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\n getItemForMention?: (triggerChar: string, key: string) => unknown;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Split a string so that newlines become <br/> elements */\nfunction textToNodes(text: string): React.ReactNode[] {\n const parts = text.split(\"\\n\");\n const nodes: React.ReactNode[] = [];\n for (let i = 0; i < parts.length; i++) {\n if (i > 0) nodes.push(React.createElement(\"br\", { key: `br-${i}` }));\n if (parts[i]) nodes.push(parts[i]);\n }\n return nodes;\n}\n\nexport const MentionHighlighter: React.FC<MentionHighlighterProps> = ({\n visible,\n mentions,\n triggers,\n textareaRef,\n getItemForMention,\n className,\n style,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n\n // Sync scroll with textarea\n useEffect(() => {\n const textarea = textareaRef.current;\n const highlighter = ref.current;\n if (!textarea || !highlighter) return;\n\n const onScroll = () => {\n highlighter.scrollTop = textarea.scrollTop;\n highlighter.scrollLeft = textarea.scrollLeft;\n };\n\n textarea.addEventListener(\"scroll\", onScroll);\n return () => textarea.removeEventListener(\"scroll\", onScroll);\n }, [textareaRef]);\n\n const children = useMemo(() => {\n const sorted = mentions.slice().sort((a, b) => a.start - b.start);\n if (!sorted.length) return textToNodes(visible);\n\n const triggerMap = new Map<string, MentionTrigger<any>>();\n for (const t of triggers) {\n triggerMap.set(t.trigger, t);\n }\n\n const nodes: React.ReactNode[] = [];\n let last = 0;\n for (let i = 0; i < sorted.length; i++) {\n const m = sorted[i]!;\n // Text before this mention\n if (last < m.start) {\n nodes.push(...textToNodes(visible.slice(last, m.start)));\n }\n\n const mentionText = visible.slice(m.start, m.end);\n const t = triggerMap.get(m.trigger);\n let cls = \"mentionize-mention\";\n if (t) {\n if (typeof t.mentionClassName === \"function\") {\n const item = getItemForMention?.(m.trigger, m.key) ?? null;\n cls = t.mentionClassName({\n key: m.key,\n displayText: m.displayText,\n trigger: m.trigger,\n item,\n });\n } else if (t.mentionClassName) {\n cls = t.mentionClassName;\n }\n }\n nodes.push(\n React.createElement(\n \"span\",\n {\n key: `mention-${i}`,\n className: cls,\n \"data-mentionize-trigger\": m.trigger,\n \"data-mentionize-key\": m.key,\n },\n mentionText\n )\n );\n last = m.end;\n }\n // after last mention\n if (last < visible.length) {\n nodes.push(...textToNodes(visible.slice(last)));\n }\n return nodes;\n }, [visible, mentions, triggers, getItemForMention]);\n\n // After render, neutralize horizontal box-model impact of mention spans\n // so user-applied padding/border/margin don't shift overlay text relative to the textarea.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const spans = el.querySelectorAll<HTMLElement>(\"[data-mentionize-trigger]\");\n for (let i = 0; i < spans.length; i++) {\n const span = spans[i]!;\n // Reset any previous compensation before measuring\n span.style.marginLeft = \"\";\n span.style.marginRight = \"\";\n const cs = getComputedStyle(span);\n const extraLeft =\n parseFloat(cs.paddingLeft) +\n parseFloat(cs.borderLeftWidth) +\n parseFloat(cs.marginLeft);\n const extraRight =\n parseFloat(cs.paddingRight) +\n parseFloat(cs.borderRightWidth) +\n parseFloat(cs.marginRight);\n if (extraLeft) span.style.marginLeft = `${-extraLeft}px`;\n if (extraRight) span.style.marginRight = `${-extraRight}px`;\n }\n });\n\n return React.createElement(\n \"div\",\n {\n ref,\n className,\n style: {\n position: \"absolute\" as const,\n inset: 0,\n pointerEvents: \"none\" as const,\n overflow: \"auto\",\n ...style,\n },\n \"aria-hidden\": true,\n \"data-mentionize-highlighter\": \"\",\n },\n ...children\n );\n};\n",
8
8
  "import { useCallback, useRef } from \"react\";\nimport type { CaretPosition } from \"./types.ts\";\n\nconst SHARED_STYLE_PROPS = [\n \"whiteSpace\",\n \"overflowWrap\",\n \"wordBreak\",\n \"padding\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"lineHeight\",\n \"letterSpacing\",\n \"tabSize\",\n \"boxSizing\",\n \"borderWidth\",\n \"borderStyle\",\n] as const;\n\nexport function useCaretPosition(dropdownWidth: number) {\n const mirrorRef = useRef<HTMLDivElement>(null);\n\n const getCaretPosition = useCallback(\n (\n textarea: HTMLTextAreaElement,\n caretIndex?: number,\n textOverride?: string\n ): CaretPosition | null => {\n const mirror = mirrorRef.current;\n if (!mirror) return null;\n\n const caret = caretIndex ?? textarea.selectionStart;\n const source = textOverride ?? textarea.value;\n const before = source.slice(0, caret);\n\n // Copy textarea computed styles to mirror\n const computed = getComputedStyle(textarea);\n for (const prop of SHARED_STYLE_PROPS) {\n (mirror.style as any)[prop] = (computed as any)[prop];\n }\n mirror.style.width = `${textarea.offsetWidth}px`;\n\n mirror.textContent = before;\n\n const span = document.createElement(\"span\");\n span.textContent = \"\\u200b\";\n mirror.appendChild(span);\n mirror.scrollTop = textarea.scrollTop;\n\n const spanRect = span.getBoundingClientRect();\n const mirrorRect = mirror.getBoundingClientRect();\n const textareaRect = textarea.getBoundingClientRect();\n\n const top =\n textareaRect.top +\n (spanRect.top - mirrorRect.top) -\n textarea.scrollTop +\n span.offsetHeight;\n let left = textareaRect.left + (spanRect.left - mirrorRect.left);\n\n // Clamp to viewport\n if (left + dropdownWidth > window.innerWidth - 8) {\n left = window.innerWidth - dropdownWidth - 8;\n }\n if (left < 8) left = 8;\n\n mirror.innerHTML = \"\";\n\n return {\n top: Math.min(Math.max(top, 8), window.innerHeight - 8),\n left,\n };\n },\n [dropdownWidth]\n );\n\n return { mirrorRef, getCaretPosition };\n}\n",
9
- "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\nimport { escapeRegex } from \"./utils.ts\";\n\ninterface ActiveTriggerState {\n trigger: MentionTrigger<any>;\n query: string;\n startPos: number; // where the trigger character is in the visible text\n}\n\ninterface SearchState {\n items: unknown[];\n page: number;\n hasMore: boolean;\n loading: boolean;\n}\n\ninterface MentionEngineOptions {\n triggers: MentionTrigger<any>[];\n value?: string;\n defaultValue?: string;\n onChange?: (raw: string) => void;\n onMentionsChange?: (mentions: ActiveMention[]) => void;\n}\n\n// Detect mentions in visible text\nfunction detectMentionsInText(\n visibleText: string,\n triggers: MentionTrigger<any>[],\n getCache: (triggerChar: string) => Map<string, unknown>,\n): ActiveMention[] {\n const all: ActiveMention[] = [];\n\n for (const t of triggers) {\n const triggerChar = t.trigger;\n if (!visibleText.includes(triggerChar)) continue;\n\n const cache = getCache(triggerChar);\n const knownItems: { displayText: string; key: string; item: unknown }[] =\n [];\n\n if (t.options) {\n for (const item of t.options) {\n knownItems.push({\n displayText: t.displayText(item),\n key: getItemKey(t, item),\n item,\n });\n }\n }\n\n for (const [key, item] of cache.entries()) {\n if (item !== null) {\n const dt = t.displayText(item);\n if (!knownItems.some((k) => k.key === key)) {\n knownItems.push({ displayText: dt, key, item });\n }\n }\n }\n\n if (!knownItems.length) continue;\n\n const compiled = knownItems.map((ki) => {\n const pat = \"^\" + escapeRegex(ki.displayText).replace(/\\s+/g, \"\\\\s+\");\n return { ...ki, re: new RegExp(pat, \"i\") };\n });\n\n const positions: number[] = [];\n let idx = visibleText.indexOf(triggerChar);\n while (idx !== -1) {\n positions.push(idx);\n idx = visibleText.indexOf(triggerChar, idx + 1);\n }\n\n const candidates: ActiveMention[] = [];\n for (const pos of positions) {\n const after = visibleText.slice(pos + triggerChar.length);\n for (const c of compiled) {\n const match = c.re.exec(after);\n if (!match) continue;\n const matched = match[0];\n const end = pos + triggerChar.length + matched.length;\n const next = visibleText[end];\n if (next && !/[\\s,.:;!?)}\\]]/.test(next)) continue;\n candidates.push({\n trigger: triggerChar,\n displayText: matched,\n key: c.key,\n start: pos,\n end,\n });\n }\n }\n\n candidates.sort((a, b) =>\n a.start !== b.start\n ? a.start - b.start\n : b.end - b.start - (a.end - a.start),\n );\n for (const c of candidates) {\n const overlaps = all.some(\n (f) => Math.max(f.start, c.start) < Math.min(f.end, c.end),\n );\n if (!overlaps) all.push(c);\n }\n }\n\n return all;\n}\n\n// Shallow-compare two mention arrays\nfunction mentionsEqual(a: ActiveMention[], b: ActiveMention[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n if (ai.start !== bi.start || ai.end !== bi.end || ai.key !== bi.key)\n return false;\n }\n return true;\n}\n\nexport function useMentionEngine(options: MentionEngineOptions) {\n const {\n triggers,\n value: controlledValue,\n defaultValue,\n onChange,\n onMentionsChange,\n } = options;\n\n const lastRawRef = useRef(controlledValue ?? defaultValue ?? \"\");\n const suppressEmitRef = useRef(false);\n const caretPosRef = useRef<number | null>(null);\n const prevMentionsRef = useRef<ActiveMention[]>([]);\n\n // Known items cache\n const cacheRef = useRef<Map<string, Map<string, unknown>>>(new Map());\n\n function getCache(triggerChar: string): Map<string, unknown> {\n let map = cacheRef.current.get(triggerChar);\n if (!map) {\n map = new Map();\n cacheRef.current.set(triggerChar, map);\n }\n return map;\n }\n\n // Populate cache from static options\n useEffect(() => {\n for (const t of triggers) {\n if (t.options) {\n const cache = getCache(t.trigger);\n for (const item of t.options) {\n const serialized = t.serialize(item);\n // Extract key by running pattern on the serialized form\n const re = new RegExp(\n t.pattern.source,\n t.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n const { key } = t.parseMatch(m);\n cache.set(key, item);\n }\n }\n }\n }\n }, [triggers]);\n\n // Convert raw to visible text\n const rawToVisible = useCallback(\n (raw: string): string => {\n let result = raw;\n for (const t of triggers) {\n const globalRe = new RegExp(\n t.pattern.source,\n t.pattern.flags.includes(\"g\")\n ? t.pattern.flags\n : t.pattern.flags + \"g\",\n );\n const parts: string[] = [];\n let lastIndex = 0;\n let m: RegExpExecArray | null;\n globalRe.lastIndex = 0;\n while ((m = globalRe.exec(result)) !== null) {\n parts.push(result.slice(lastIndex, m.index));\n const parsed = t.parseMatch(m);\n // Cache the item data from the match\n const cache = getCache(t.trigger);\n // placeholder for unmatched items\n if (!cache.has(parsed.key)) {\n cache.set(parsed.key, null);\n }\n parts.push(t.trigger + parsed.displayText);\n lastIndex = m.index + m[0].length;\n if (!t.pattern.flags.includes(\"g\")) break;\n }\n parts.push(result.slice(lastIndex));\n result = parts.join(\"\");\n }\n return result;\n },\n [triggers],\n );\n\n // Initialize visible text from raw\n const [visible, setVisible] = useState<string>(() =>\n rawToVisible(controlledValue ?? defaultValue ?? \"\"),\n );\n\n // Detect mentions in visible text\n const mentions: ActiveMention[] = useMemo(() => {\n const newMentions = detectMentionsInText(visible, triggers, getCache);\n if (mentionsEqual(prevMentionsRef.current, newMentions)) {\n return prevMentionsRef.current;\n }\n prevMentionsRef.current = newMentions;\n return newMentions;\n }, [visible, triggers]);\n\n // Build raw value from visible + mentions\n const visibleToRaw = useCallback(\n (vis: string, mentionsList: ActiveMention[]): string => {\n if (!mentionsList.length) return vis;\n const ordered = mentionsList.slice().sort((a, b) => a.start - b.start);\n let raw = \"\";\n let last = 0;\n for (const m of ordered) {\n raw += vis.slice(last, m.start);\n // Find the trigger config and the cached item\n const t = triggers.find((tr) => tr.trigger === m.trigger);\n if (t) {\n const cache = getCache(t.trigger);\n const item = cache.get(m.key);\n if (item !== null && item !== undefined) {\n raw += t.serialize(item);\n } else {\n raw += vis.slice(m.start, m.end);\n }\n } else {\n raw += vis.slice(m.start, m.end);\n }\n last = m.end;\n }\n raw += vis.slice(last);\n return raw;\n },\n [triggers],\n );\n\n // Synchronously emit raw value + mentions after visible text changes\n const emitSync = useCallback(\n (newVisible: string) => {\n const newMentions = detectMentionsInText(newVisible, triggers, getCache);\n\n if (!mentionsEqual(prevMentionsRef.current, newMentions)) {\n prevMentionsRef.current = newMentions;\n }\n\n const raw = visibleToRaw(newVisible, prevMentionsRef.current);\n if (raw !== lastRawRef.current) {\n lastRawRef.current = raw;\n onChange?.(raw);\n }\n onMentionsChange?.(prevMentionsRef.current);\n },\n [triggers, visibleToRaw, onChange, onMentionsChange],\n );\n\n useEffect(() => {\n if (controlledValue === undefined) return;\n if (controlledValue === lastRawRef.current) return;\n lastRawRef.current = controlledValue;\n suppressEmitRef.current = true;\n setVisible(rawToVisible(controlledValue));\n }, [controlledValue, rawToVisible]);\n\n const [activeTrigger, setActiveTrigger] = useState<ActiveTriggerState | null>(\n null,\n );\n const [searchState, setSearchState] = useState<SearchState>({\n items: [],\n page: 0,\n hasMore: false,\n loading: false,\n });\n const [highlightIndex, setHighlightIndex] = useState(0);\n const searchAbortRef = useRef<AbortController | null>(null);\n\n const detectActiveTrigger = useCallback(\n (text: string, caretPos: number): ActiveTriggerState | null => {\n // Look backwards from caret for any trigger character\n const prefix = text.slice(0, caretPos);\n for (const t of triggers) {\n const triggerChar = t.trigger;\n // Find the last occurrence of trigger char before caret\n const re = new RegExp(\n escapeRegex(triggerChar) +\n \"([^\\\\n\" +\n escapeRegex(triggerChar) +\n \"]*)$\",\n );\n const match = re.exec(prefix);\n if (match && match[1] !== undefined) {\n const query = match[1];\n // Don't activate if query contains whitespace (user moved on)\n if (/\\s/.test(query)) continue;\n return {\n trigger: t,\n query,\n startPos: match.index,\n };\n }\n }\n return null;\n },\n [triggers],\n );\n\n // Get filtered options for current trigger\n const filteredOptions = useMemo(() => {\n if (!activeTrigger) return [];\n const t = activeTrigger.trigger;\n const q = activeTrigger.query.toLowerCase();\n\n if (t.onSearch) {\n // Async mode returns search state items\n return searchState.items;\n }\n\n if (t.options) {\n if (!q) return t.options;\n return t.options.filter((item) =>\n t.displayText(item).toLowerCase().includes(q),\n );\n }\n\n return [];\n }, [activeTrigger, searchState.items]);\n\n useEffect(() => {\n if (!activeTrigger?.trigger.onSearch) return;\n\n const t = activeTrigger.trigger;\n const query = activeTrigger.query;\n\n // Abort previous search\n searchAbortRef.current?.abort();\n const controller = new AbortController();\n searchAbortRef.current = controller;\n\n setSearchState((s) => ({ ...s, loading: true, page: 0 }));\n\n const timer = setTimeout(async () => {\n try {\n const result = await t.onSearch!(query, 0);\n if (controller.signal.aborted) return;\n setSearchState({\n items: result.items,\n page: 0,\n hasMore: result.hasMore,\n loading: false,\n });\n } catch {\n if (controller.signal.aborted) return;\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, 150);\n\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [activeTrigger?.trigger, activeTrigger?.query]);\n\n const loadMore = useCallback(async () => {\n if (\n !activeTrigger?.trigger.onSearch ||\n searchState.loading ||\n !searchState.hasMore\n )\n return;\n\n const t = activeTrigger.trigger;\n const nextPage = searchState.page + 1;\n setSearchState((s) => ({ ...s, loading: true }));\n\n try {\n const result = await t.onSearch!(activeTrigger.query, nextPage);\n setSearchState((s) => ({\n items: [...s.items, ...result.items],\n page: nextPage,\n hasMore: result.hasMore,\n loading: false,\n }));\n } catch {\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, [activeTrigger, searchState]);\n\n // Handle text change from textarea\n const handleTextChange = useCallback(\n (newText: string, caretPos: number) => {\n caretPosRef.current = caretPos;\n setVisible(newText);\n emitSync(newText);\n const detected = detectActiveTrigger(newText, caretPos);\n if (detected) {\n setActiveTrigger(detected);\n setHighlightIndex(0);\n } else {\n setActiveTrigger(null);\n }\n },\n [detectActiveTrigger, emitSync],\n );\n\n // Select an option from the dropdown\n const selectOption = useCallback(\n (item: unknown, textarea: HTMLTextAreaElement) => {\n if (!activeTrigger) return;\n const t = activeTrigger.trigger;\n\n // Add to cache\n const cache = getCache(t.trigger);\n const key = getItemKey(t, item);\n cache.set(key, item);\n\n const displayText = t.displayText(item);\n const mentionText = t.trigger + displayText;\n\n const before = visible.slice(0, activeTrigger.startPos);\n const after = visible.slice(textarea.selectionStart);\n const newVis = before + mentionText + \" \" + after;\n\n const pos = before.length + mentionText.length + 1;\n caretPosRef.current = pos;\n setVisible(newVis);\n emitSync(newVis);\n setActiveTrigger(null);\n },\n [activeTrigger, visible, emitSync],\n );\n\n const closeSuggestions = useCallback(() => {\n setActiveTrigger(null);\n setSearchState({ items: [], page: 0, hasMore: false, loading: false });\n }, []);\n\n // Keyboard handling\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, textarea: HTMLTextAreaElement): boolean => {\n if (!activeTrigger) return false;\n\n const len = filteredOptions.length;\n if (!len && !searchState.loading) return false;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n const next = (highlightIndex + 1) % Math.max(len, 1);\n setHighlightIndex(next);\n // Trigger load more near end\n if (\n len - 1 - next <= 3 &&\n searchState.hasMore &&\n !searchState.loading\n ) {\n loadMore();\n }\n return true;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setHighlightIndex(\n (highlightIndex - 1 + Math.max(len, 1)) % Math.max(len, 1),\n );\n return true;\n }\n if (e.key === \"Enter\") {\n e.preventDefault();\n const item = filteredOptions[highlightIndex];\n if (item) selectOption(item, textarea);\n return true;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n closeSuggestions();\n return true;\n }\n return false;\n },\n [\n activeTrigger,\n filteredOptions,\n highlightIndex,\n searchState,\n selectOption,\n closeSuggestions,\n loadMore,\n ],\n );\n\n return {\n visible,\n setVisible,\n mentions,\n activeTrigger,\n filteredOptions,\n highlightIndex,\n setHighlightIndex,\n searchLoading: searchState.loading,\n searchHasMore: searchState.hasMore,\n handleTextChange,\n handleKeyDown,\n selectOption,\n closeSuggestions,\n loadMore,\n rawToVisible,\n visibleToRaw,\n caretPosRef,\n };\n}\n\nfunction getItemKey(trigger: MentionTrigger<any>, item: unknown): string {\n const serialized = trigger.serialize(item);\n const re = new RegExp(\n trigger.pattern.source,\n trigger.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n return trigger.parseMatch(m).key;\n }\n return serialized;\n}\n",
9
+ "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\nimport { escapeRegex } from \"./utils.ts\";\n\ninterface ActiveTriggerState {\n trigger: MentionTrigger<any>;\n query: string;\n startPos: number; // where the trigger character is in the visible text\n}\n\ninterface SearchState {\n items: unknown[];\n page: number;\n hasMore: boolean;\n loading: boolean;\n}\n\ninterface MentionEngineOptions {\n triggers: MentionTrigger<any>[];\n value?: string;\n defaultValue?: string;\n onChange?: (raw: string) => void;\n onMentionsChange?: (mentions: ActiveMention[]) => void;\n}\n\n// Detect mentions in visible text\nfunction detectMentionsInText(\n visibleText: string,\n triggers: MentionTrigger<any>[],\n getCache: (triggerChar: string) => Map<string, unknown>,\n): ActiveMention[] {\n const all: ActiveMention[] = [];\n\n for (const t of triggers) {\n const triggerChar = t.trigger;\n if (!visibleText.includes(triggerChar)) continue;\n\n const cache = getCache(triggerChar);\n const knownItems: { displayText: string; key: string; item: unknown }[] =\n [];\n\n if (t.options) {\n for (const item of t.options) {\n knownItems.push({\n displayText: t.displayText(item),\n key: getItemKey(t, item),\n item,\n });\n }\n }\n\n for (const [key, item] of cache.entries()) {\n if (item !== null) {\n const dt = t.displayText(item);\n if (!knownItems.some((k) => k.key === key)) {\n knownItems.push({ displayText: dt, key, item });\n }\n }\n }\n\n if (!knownItems.length) continue;\n\n const compiled = knownItems.map((ki) => {\n const pat = \"^\" + escapeRegex(ki.displayText).replace(/\\s+/g, \"\\\\s+\");\n return { ...ki, re: new RegExp(pat, \"i\") };\n });\n\n const positions: number[] = [];\n let idx = visibleText.indexOf(triggerChar);\n while (idx !== -1) {\n positions.push(idx);\n idx = visibleText.indexOf(triggerChar, idx + 1);\n }\n\n const candidates: ActiveMention[] = [];\n for (const pos of positions) {\n const after = visibleText.slice(pos + triggerChar.length);\n for (const c of compiled) {\n const match = c.re.exec(after);\n if (!match) continue;\n const matched = match[0];\n const end = pos + triggerChar.length + matched.length;\n const next = visibleText[end];\n if (next && !/[\\s,.:;!?)}\\]]/.test(next)) continue;\n candidates.push({\n trigger: triggerChar,\n displayText: matched,\n key: c.key,\n start: pos,\n end,\n });\n }\n }\n\n candidates.sort((a, b) =>\n a.start !== b.start\n ? a.start - b.start\n : b.end - b.start - (a.end - a.start),\n );\n for (const c of candidates) {\n const overlaps = all.some(\n (f) => Math.max(f.start, c.start) < Math.min(f.end, c.end),\n );\n if (!overlaps) all.push(c);\n }\n }\n\n return all;\n}\n\n// Shallow-compare two mention arrays\nfunction mentionsEqual(a: ActiveMention[], b: ActiveMention[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n if (ai.start !== bi.start || ai.end !== bi.end || ai.key !== bi.key)\n return false;\n }\n return true;\n}\n\nexport function useMentionEngine(options: MentionEngineOptions) {\n const {\n triggers,\n value: controlledValue,\n defaultValue,\n onChange,\n onMentionsChange,\n } = options;\n\n const lastRawRef = useRef(controlledValue ?? defaultValue ?? \"\");\n const suppressEmitRef = useRef(false);\n const caretPosRef = useRef<number | null>(null);\n const prevMentionsRef = useRef<ActiveMention[]>([]);\n\n // Known items cache\n const cacheRef = useRef<Map<string, Map<string, unknown>>>(new Map());\n\n function getCache(triggerChar: string): Map<string, unknown> {\n let map = cacheRef.current.get(triggerChar);\n if (!map) {\n map = new Map();\n cacheRef.current.set(triggerChar, map);\n }\n return map;\n }\n\n // Populate cache from static options\n useEffect(() => {\n for (const t of triggers) {\n if (t.options) {\n const cache = getCache(t.trigger);\n for (const item of t.options) {\n const serialized = t.serialize(item);\n // Extract key by running pattern on the serialized form\n const re = new RegExp(\n t.pattern.source,\n t.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n const { key } = t.parseMatch(m);\n cache.set(key, item);\n }\n }\n }\n }\n }, [triggers]);\n\n // Convert raw to visible text\n const rawToVisible = useCallback(\n (raw: string): string => {\n let result = raw;\n for (const t of triggers) {\n const globalRe = new RegExp(\n t.pattern.source,\n t.pattern.flags.includes(\"g\")\n ? t.pattern.flags\n : t.pattern.flags + \"g\",\n );\n const parts: string[] = [];\n let lastIndex = 0;\n let m: RegExpExecArray | null;\n globalRe.lastIndex = 0;\n while ((m = globalRe.exec(result)) !== null) {\n parts.push(result.slice(lastIndex, m.index));\n const parsed = t.parseMatch(m);\n // Cache the item data from the match\n const cache = getCache(t.trigger);\n // placeholder for unmatched items\n if (!cache.has(parsed.key)) {\n cache.set(parsed.key, null);\n }\n parts.push(t.trigger + parsed.displayText);\n lastIndex = m.index + m[0].length;\n if (!t.pattern.flags.includes(\"g\")) break;\n }\n parts.push(result.slice(lastIndex));\n result = parts.join(\"\");\n }\n return result;\n },\n [triggers],\n );\n\n // Initialize visible text from raw\n const [visible, setVisible] = useState<string>(() =>\n rawToVisible(controlledValue ?? defaultValue ?? \"\"),\n );\n\n // Detect mentions in visible text\n const mentions: ActiveMention[] = useMemo(() => {\n const newMentions = detectMentionsInText(visible, triggers, getCache);\n if (mentionsEqual(prevMentionsRef.current, newMentions)) {\n return prevMentionsRef.current;\n }\n prevMentionsRef.current = newMentions;\n return newMentions;\n }, [visible, triggers]);\n\n // Build raw value from visible + mentions\n const visibleToRaw = useCallback(\n (vis: string, mentionsList: ActiveMention[]): string => {\n if (!mentionsList.length) return vis;\n const ordered = mentionsList.slice().sort((a, b) => a.start - b.start);\n let raw = \"\";\n let last = 0;\n for (const m of ordered) {\n raw += vis.slice(last, m.start);\n // Find the trigger config and the cached item\n const t = triggers.find((tr) => tr.trigger === m.trigger);\n if (t) {\n const cache = getCache(t.trigger);\n const item = cache.get(m.key);\n if (item !== null && item !== undefined) {\n raw += t.serialize(item);\n } else {\n raw += vis.slice(m.start, m.end);\n }\n } else {\n raw += vis.slice(m.start, m.end);\n }\n last = m.end;\n }\n raw += vis.slice(last);\n return raw;\n },\n [triggers],\n );\n\n // Synchronously emit raw value + mentions after visible text changes\n const emitSync = useCallback(\n (newVisible: string) => {\n const newMentions = detectMentionsInText(newVisible, triggers, getCache);\n\n if (!mentionsEqual(prevMentionsRef.current, newMentions)) {\n prevMentionsRef.current = newMentions;\n }\n\n const raw = visibleToRaw(newVisible, prevMentionsRef.current);\n if (raw !== lastRawRef.current) {\n lastRawRef.current = raw;\n onChange?.(raw);\n }\n onMentionsChange?.(prevMentionsRef.current);\n },\n [triggers, visibleToRaw, onChange, onMentionsChange],\n );\n\n useEffect(() => {\n if (controlledValue === undefined) return;\n if (controlledValue === lastRawRef.current) return;\n lastRawRef.current = controlledValue;\n suppressEmitRef.current = true;\n setVisible(rawToVisible(controlledValue));\n }, [controlledValue, rawToVisible]);\n\n const [activeTrigger, setActiveTrigger] = useState<ActiveTriggerState | null>(\n null,\n );\n const [searchState, setSearchState] = useState<SearchState>({\n items: [],\n page: 0,\n hasMore: false,\n loading: false,\n });\n const [highlightIndex, setHighlightIndex] = useState(0);\n const searchAbortRef = useRef<AbortController | null>(null);\n\n const detectActiveTrigger = useCallback(\n (text: string, caretPos: number): ActiveTriggerState | null => {\n // Look backwards from caret for any trigger character\n const prefix = text.slice(0, caretPos);\n for (const t of triggers) {\n const triggerChar = t.trigger;\n // Find the last occurrence of trigger char before caret\n const re = new RegExp(\n escapeRegex(triggerChar) +\n \"([^\\\\n\" +\n escapeRegex(triggerChar) +\n \"]*)$\",\n );\n const match = re.exec(prefix);\n if (match && match[1] !== undefined) {\n const query = match[1];\n // Don't activate if query contains whitespace (user moved on)\n if (/\\s/.test(query)) continue;\n return {\n trigger: t,\n query,\n startPos: match.index,\n };\n }\n }\n return null;\n },\n [triggers],\n );\n\n // Get filtered options for current trigger\n const filteredOptions = useMemo(() => {\n if (!activeTrigger) return [];\n const t = activeTrigger.trigger;\n const q = activeTrigger.query.toLowerCase();\n\n if (t.onSearch) {\n // Async mode returns search state items\n return searchState.items;\n }\n\n if (t.options) {\n if (!q) return t.options;\n return t.options.filter((item) =>\n t.displayText(item).toLowerCase().includes(q),\n );\n }\n\n return [];\n }, [activeTrigger, searchState.items]);\n\n useEffect(() => {\n if (!activeTrigger?.trigger.onSearch) return;\n\n const t = activeTrigger.trigger;\n const query = activeTrigger.query;\n\n // Abort previous search\n searchAbortRef.current?.abort();\n const controller = new AbortController();\n searchAbortRef.current = controller;\n\n setSearchState((s) => ({ ...s, loading: true, page: 0 }));\n\n const timer = setTimeout(async () => {\n try {\n const result = await t.onSearch!(query, 0);\n if (controller.signal.aborted) return;\n setSearchState({\n items: result.items,\n page: 0,\n hasMore: result.hasMore,\n loading: false,\n });\n } catch {\n if (controller.signal.aborted) return;\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, 150);\n\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [activeTrigger?.trigger, activeTrigger?.query]);\n\n const loadMore = useCallback(async () => {\n if (\n !activeTrigger?.trigger.onSearch ||\n searchState.loading ||\n !searchState.hasMore\n )\n return;\n\n const t = activeTrigger.trigger;\n const nextPage = searchState.page + 1;\n setSearchState((s) => ({ ...s, loading: true }));\n\n try {\n const result = await t.onSearch!(activeTrigger.query, nextPage);\n setSearchState((s) => ({\n items: [...s.items, ...result.items],\n page: nextPage,\n hasMore: result.hasMore,\n loading: false,\n }));\n } catch {\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, [activeTrigger, searchState]);\n\n // Handle text change from textarea\n const handleTextChange = useCallback(\n (newText: string, caretPos: number) => {\n caretPosRef.current = caretPos;\n setVisible(newText);\n emitSync(newText);\n const detected = detectActiveTrigger(newText, caretPos);\n if (detected) {\n setActiveTrigger(detected);\n setHighlightIndex(0);\n } else {\n setActiveTrigger(null);\n }\n },\n [detectActiveTrigger, emitSync],\n );\n\n // Look up a cached item for a mention\n const getItemForMention = useCallback(\n (triggerChar: string, key: string): unknown => {\n const cache = getCache(triggerChar);\n return cache.get(key) ?? null;\n },\n [],\n );\n\n // Select an option from the dropdown\n const selectOption = useCallback(\n (item: unknown, textarea: HTMLTextAreaElement) => {\n if (!activeTrigger) return;\n const t = activeTrigger.trigger;\n\n if (t.onSelect) {\n // Action trigger mode: close dropdown, remove trigger+query, call onSelect\n const before = visible.slice(0, activeTrigger.startPos);\n const after = visible.slice(textarea.selectionStart);\n const savedStartPos = activeTrigger.startPos;\n\n setActiveTrigger(null);\n\n const result = t.onSelect(item);\n const applyResult = (value: string | null) => {\n if (value !== null) {\n const newVis = before + value + after;\n const pos = savedStartPos + value.length;\n caretPosRef.current = pos;\n setVisible(newVis);\n emitSync(newVis);\n } else {\n // null = cancel, just remove the trigger+query\n const newVis = before + after;\n caretPosRef.current = savedStartPos;\n setVisible(newVis);\n emitSync(newVis);\n }\n };\n\n if (result instanceof Promise) {\n result.then(applyResult);\n } else {\n applyResult(result);\n }\n return;\n }\n\n // Standard mention mode\n const cache = getCache(t.trigger);\n const key = getItemKey(t, item);\n cache.set(key, item);\n\n const displayText = t.displayText(item);\n const mentionText = t.trigger + displayText;\n\n const before = visible.slice(0, activeTrigger.startPos);\n const after = visible.slice(textarea.selectionStart);\n const newVis = before + mentionText + \" \" + after;\n\n const pos = before.length + mentionText.length + 1;\n caretPosRef.current = pos;\n setVisible(newVis);\n emitSync(newVis);\n setActiveTrigger(null);\n },\n [activeTrigger, visible, emitSync],\n );\n\n const closeSuggestions = useCallback(() => {\n setActiveTrigger(null);\n setSearchState({ items: [], page: 0, hasMore: false, loading: false });\n }, []);\n\n // Keyboard handling\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, textarea: HTMLTextAreaElement): boolean => {\n if (!activeTrigger) return false;\n\n const len = filteredOptions.length;\n if (!len && !searchState.loading) return false;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n const next = (highlightIndex + 1) % Math.max(len, 1);\n setHighlightIndex(next);\n // Trigger load more near end\n if (\n len - 1 - next <= 3 &&\n searchState.hasMore &&\n !searchState.loading\n ) {\n loadMore();\n }\n return true;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setHighlightIndex(\n (highlightIndex - 1 + Math.max(len, 1)) % Math.max(len, 1),\n );\n return true;\n }\n if (e.key === \"Enter\") {\n e.preventDefault();\n const item = filteredOptions[highlightIndex];\n if (item) selectOption(item, textarea);\n return true;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n closeSuggestions();\n return true;\n }\n return false;\n },\n [\n activeTrigger,\n filteredOptions,\n highlightIndex,\n searchState,\n selectOption,\n closeSuggestions,\n loadMore,\n ],\n );\n\n return {\n visible,\n setVisible,\n mentions,\n activeTrigger,\n filteredOptions,\n highlightIndex,\n setHighlightIndex,\n searchLoading: searchState.loading,\n searchHasMore: searchState.hasMore,\n handleTextChange,\n handleKeyDown,\n selectOption,\n closeSuggestions,\n loadMore,\n rawToVisible,\n visibleToRaw,\n caretPosRef,\n getItemForMention,\n };\n}\n\nfunction getItemKey(trigger: MentionTrigger<any>, item: unknown): string {\n const serialized = trigger.serialize(item);\n const re = new RegExp(\n trigger.pattern.source,\n trigger.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n return trigger.parseMatch(m).key;\n }\n return serialized;\n}\n",
10
10
  "export function escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "2D34F896A558FE4664756E2164756E21",
12
+ "mappings": "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",
13
+ "debugId": "E1E2DCC63463DE3264756E2164756E21",
14
14
  "names": []
15
15
  }
@@ -1,4 +1,10 @@
1
1
  import type React from "react";
2
+ export interface MentionItemData {
3
+ key: string;
4
+ displayText: string;
5
+ trigger: string;
6
+ item: unknown;
7
+ }
2
8
  export interface MentionTrigger<T = unknown> {
3
9
  /** The character(s) that activate this trigger (e.g., "@", "#") */
4
10
  trigger: string;
@@ -22,10 +28,14 @@ export interface MentionTrigger<T = unknown> {
22
28
  }>;
23
29
  /** Custom option rendering */
24
30
  renderOption?: (item: T, highlighted: boolean) => React.ReactNode;
31
+ /** CSS class for dropdown options, or a function for conditional styling per item */
32
+ optionClassName?: string | ((item: T) => string);
25
33
  /** Custom mention highlight rendering */
26
- renderMention?: (displayText: string) => React.ReactNode;
27
- /** CSS class for highlighted mentions in the overlay */
28
- mentionClassName?: string;
34
+ renderMention?: (displayText: string, item?: unknown) => React.ReactNode;
35
+ /** CSS class for highlighted mentions in the overlay, or a function for conditional styling */
36
+ mentionClassName?: string | ((mention: MentionItemData) => string);
37
+ /** Action trigger: called instead of inserting a mention. Return string to insert as plain text, or null to cancel. */
38
+ onSelect?: (item: T) => Promise<string | null> | string | null;
29
39
  }
30
40
  export interface MentionInputProps {
31
41
  triggers: MentionTrigger<any>[];
@@ -48,6 +58,8 @@ export interface MentionInputProps {
48
58
  dropdownClassName?: string;
49
59
  /** Dropdown width in pixels */
50
60
  dropdownWidth?: number;
61
+ /** Text shown while loading async results (default: "Loading...") */
62
+ loadingText?: string;
51
63
  /** Full custom dropdown rendering */
52
64
  renderDropdown?: (props: DropdownRenderProps) => React.ReactNode;
53
65
  "aria-label"?: string;
@@ -29,5 +29,6 @@ export declare function useMentionEngine(options: MentionEngineOptions): {
29
29
  rawToVisible: (raw: string) => string;
30
30
  visibleToRaw: (vis: string, mentionsList: ActiveMention[]) => string;
31
31
  caretPosRef: import("react").RefObject<number | null>;
32
+ getItemForMention: (triggerChar: string, key: string) => unknown;
32
33
  };
33
34
  export {};
@@ -8,6 +8,7 @@ interface MentionDropdownProps {
8
8
  onSelect: (item: unknown) => void;
9
9
  onLoadMore?: () => void;
10
10
  loading: boolean;
11
+ loadingText?: string;
11
12
  position: CaretPosition;
12
13
  width: number;
13
14
  className?: string;
@@ -5,6 +5,7 @@ interface MentionHighlighterProps {
5
5
  mentions: ActiveMention[];
6
6
  triggers: MentionTrigger<any>[];
7
7
  textareaRef: React.RefObject<HTMLTextAreaElement | null>;
8
+ getItemForMention?: (triggerChar: string, key: string) => unknown;
8
9
  className?: string;
9
10
  style?: React.CSSProperties;
10
11
  }
@@ -3,4 +3,4 @@ export { MentionHighlighter } from "./MentionHighlighter.tsx";
3
3
  export { MentionDropdown } from "./MentionDropdown.tsx";
4
4
  export { useMentionEngine } from "./useMentionEngine.ts";
5
5
  export { useCaretPosition } from "./useCaretPosition.ts";
6
- export type { MentionTrigger, MentionInputProps, ActiveMention, DropdownRenderProps, CaretPosition, } from "./types.ts";
6
+ export type { MentionTrigger, MentionItemData, MentionInputProps, ActiveMention, DropdownRenderProps, CaretPosition, } from "./types.ts";
package/dist/esm/index.js CHANGED
@@ -20,6 +20,7 @@ var MentionDropdown = ({
20
20
  onSelect,
21
21
  onLoadMore,
22
22
  loading,
23
+ loadingText,
23
24
  position,
24
25
  width,
25
26
  className
@@ -74,10 +75,12 @@ var MentionDropdown = ({
74
75
  children: [
75
76
  items.map((item, i) => {
76
77
  const isHighlighted = i === highlightedIndex;
78
+ const optCls = typeof trigger.optionClassName === "function" ? trigger.optionClassName(item) : trigger.optionClassName;
77
79
  if (trigger.renderOption) {
78
80
  return /* @__PURE__ */ jsxDEV("div", {
79
81
  role: "option",
80
82
  "aria-selected": isHighlighted,
83
+ className: optCls,
81
84
  "data-mentionize-option-index": i,
82
85
  "data-mentionize-option-highlighted": isHighlighted || undefined,
83
86
  onMouseEnter: () => onHighlight(i),
@@ -88,6 +91,7 @@ var MentionDropdown = ({
88
91
  return /* @__PURE__ */ jsxDEV("div", {
89
92
  role: "option",
90
93
  "aria-selected": isHighlighted,
94
+ className: optCls,
91
95
  "data-mentionize-option-index": i,
92
96
  "data-mentionize-option": "",
93
97
  "data-mentionize-option-highlighted": isHighlighted || undefined,
@@ -98,7 +102,7 @@ var MentionDropdown = ({
98
102
  }),
99
103
  loading && /* @__PURE__ */ jsxDEV("div", {
100
104
  "data-mentionize-loading": "",
101
- children: "Loading..."
105
+ children: loadingText ?? "Loading..."
102
106
  }, undefined, false, undefined, this),
103
107
  onLoadMore && !loading && /* @__PURE__ */ jsxDEV("div", {
104
108
  ref: sentinelRef,
@@ -128,6 +132,7 @@ var MentionHighlighter = ({
128
132
  mentions,
129
133
  triggers,
130
134
  textareaRef,
135
+ getItemForMention,
131
136
  className,
132
137
  style
133
138
  }) => {
@@ -148,9 +153,9 @@ var MentionHighlighter = ({
148
153
  const sorted = mentions.slice().sort((a, b) => a.start - b.start);
149
154
  if (!sorted.length)
150
155
  return textToNodes(visible);
151
- const classMap = new Map;
156
+ const triggerMap = new Map;
152
157
  for (const t of triggers) {
153
- classMap.set(t.trigger, t.mentionClassName ?? "mentionize-mention");
158
+ triggerMap.set(t.trigger, t);
154
159
  }
155
160
  const nodes = [];
156
161
  let last = 0;
@@ -160,7 +165,21 @@ var MentionHighlighter = ({
160
165
  nodes.push(...textToNodes(visible.slice(last, m.start)));
161
166
  }
162
167
  const mentionText = visible.slice(m.start, m.end);
163
- const cls = classMap.get(m.trigger) ?? "mentionize-mention";
168
+ const t = triggerMap.get(m.trigger);
169
+ let cls = "mentionize-mention";
170
+ if (t) {
171
+ if (typeof t.mentionClassName === "function") {
172
+ const item = getItemForMention?.(m.trigger, m.key) ?? null;
173
+ cls = t.mentionClassName({
174
+ key: m.key,
175
+ displayText: m.displayText,
176
+ trigger: m.trigger,
177
+ item
178
+ });
179
+ } else if (t.mentionClassName) {
180
+ cls = t.mentionClassName;
181
+ }
182
+ }
164
183
  nodes.push(React2.createElement("span", {
165
184
  key: `mention-${i}`,
166
185
  className: cls,
@@ -173,7 +192,7 @@ var MentionHighlighter = ({
173
192
  nodes.push(...textToNodes(visible.slice(last)));
174
193
  }
175
194
  return nodes;
176
- }, [visible, mentions, triggers]);
195
+ }, [visible, mentions, triggers, getItemForMention]);
177
196
  useLayoutEffect(() => {
178
197
  const el = ref.current;
179
198
  if (!el)
@@ -574,10 +593,41 @@ function useMentionEngine(options) {
574
593
  setActiveTrigger(null);
575
594
  }
576
595
  }, [detectActiveTrigger, emitSync]);
596
+ const getItemForMention = useCallback3((triggerChar, key) => {
597
+ const cache = getCache(triggerChar);
598
+ return cache.get(key) ?? null;
599
+ }, []);
577
600
  const selectOption = useCallback3((item, textarea) => {
578
601
  if (!activeTrigger)
579
602
  return;
580
603
  const t = activeTrigger.trigger;
604
+ if (t.onSelect) {
605
+ const before2 = visible.slice(0, activeTrigger.startPos);
606
+ const after2 = visible.slice(textarea.selectionStart);
607
+ const savedStartPos = activeTrigger.startPos;
608
+ setActiveTrigger(null);
609
+ const result = t.onSelect(item);
610
+ const applyResult = (value) => {
611
+ if (value !== null) {
612
+ const newVis2 = before2 + value + after2;
613
+ const pos2 = savedStartPos + value.length;
614
+ caretPosRef.current = pos2;
615
+ setVisible(newVis2);
616
+ emitSync(newVis2);
617
+ } else {
618
+ const newVis2 = before2 + after2;
619
+ caretPosRef.current = savedStartPos;
620
+ setVisible(newVis2);
621
+ emitSync(newVis2);
622
+ }
623
+ };
624
+ if (result instanceof Promise) {
625
+ result.then(applyResult);
626
+ } else {
627
+ applyResult(result);
628
+ }
629
+ return;
630
+ }
581
631
  const cache = getCache(t.trigger);
582
632
  const key = getItemKey(t, item);
583
633
  cache.set(key, item);
@@ -655,7 +705,8 @@ function useMentionEngine(options) {
655
705
  loadMore,
656
706
  rawToVisible,
657
707
  visibleToRaw,
658
- caretPosRef
708
+ caretPosRef,
709
+ getItemForMention
659
710
  };
660
711
  }
661
712
  function getItemKey(trigger, item) {
@@ -695,6 +746,7 @@ var MentionInput = forwardRef(({
695
746
  highlighterClassName,
696
747
  dropdownClassName,
697
748
  dropdownWidth = 250,
749
+ loadingText,
698
750
  renderDropdown,
699
751
  "aria-label": ariaLabel,
700
752
  "aria-describedby": ariaDescribedBy
@@ -767,6 +819,7 @@ var MentionInput = forwardRef(({
767
819
  mentions: engine.mentions,
768
820
  triggers,
769
821
  textareaRef,
822
+ getItemForMention: engine.getItemForMention,
770
823
  className: highlighterClassName,
771
824
  style: SHARED_STYLE
772
825
  }, undefined, false, undefined, this),
@@ -824,6 +877,7 @@ var MentionInput = forwardRef(({
824
877
  onSelect: handleSelect,
825
878
  onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,
826
879
  loading: engine.searchLoading,
880
+ loadingText,
827
881
  position: dropdownPos,
828
882
  width: dropdownWidth,
829
883
  className: dropdownClassName
@@ -840,5 +894,5 @@ export {
840
894
  MentionDropdown
841
895
  };
842
896
 
843
- //# debugId=436A2E507826B04564756E2164756E21
897
+ //# debugId=0811411863941EFA64756E2164756E21
844
898
  //# sourceMappingURL=index.js.map
@@ -2,14 +2,14 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/MentionInput.tsx", "../../src/MentionDropdown.tsx", "../../src/MentionHighlighter.tsx", "../../src/useCaretPosition.ts", "../../src/useMentionEngine.ts", "../../src/utils.ts"],
4
4
  "sourcesContent": [
5
- "import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { MentionDropdown } from \"./MentionDropdown.tsx\";\nimport { MentionHighlighter } from \"./MentionHighlighter.tsx\";\nimport type { CaretPosition, MentionInputProps } from \"./types.ts\";\nimport { useCaretPosition } from \"./useCaretPosition.ts\";\nimport { useMentionEngine } from \"./useMentionEngine.ts\";\n\nconst SHARED_STYLE: React.CSSProperties = {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"anywhere\",\n wordBreak: \"break-word\",\n padding: \"0.5rem 0.75rem\",\n fontFamily: \"inherit\",\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n letterSpacing: \"normal\",\n boxSizing: \"border-box\",\n};\n\nexport const MentionInput = forwardRef<HTMLTextAreaElement, MentionInputProps>(\n (\n {\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n placeholder,\n disabled,\n rows = 4,\n className,\n inputClassName,\n highlighterClassName,\n dropdownClassName,\n dropdownWidth = 250,\n renderDropdown,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n },\n ref\n ) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n useImperativeHandle(ref, () => textareaRef.current!);\n\n const engine = useMentionEngine({\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n });\n\n // Restore caret position after render, then clear so we don't\n // fight the browser on subsequent renders (like arrow-key navigation)\n useLayoutEffect(() => {\n const pos = engine.caretPosRef.current;\n const ta = textareaRef.current;\n if (pos !== null && ta && document.activeElement === ta) {\n ta.setSelectionRange(pos, pos);\n engine.caretPosRef.current = null;\n }\n });\n\n const { mirrorRef, getCaretPosition } = useCaretPosition(dropdownWidth);\n const [dropdownPos, setDropdownPos] = useState<CaretPosition | null>(null);\n\n // Update dropdown position when active trigger changes\n useEffect(() => {\n if (engine.activeTrigger && textareaRef.current) {\n requestAnimationFrame(() => {\n const pos = getCaretPosition(textareaRef.current!);\n if (pos) setDropdownPos(pos);\n });\n } else {\n setDropdownPos(null);\n }\n }, [engine.activeTrigger, engine.visible, getCaretPosition]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n engine.handleTextChange(e.target.value, e.target.selectionStart);\n },\n [engine.handleTextChange]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (textareaRef.current) {\n engine.handleKeyDown(e, textareaRef.current);\n }\n },\n [engine.handleKeyDown]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const ta = textareaRef.current;\n if (!ta) return;\n const txt = e.clipboardData.getData(\"text\");\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const newText =\n engine.visible.slice(0, start) + txt + engine.visible.slice(end);\n e.preventDefault();\n engine.handleTextChange(newText, start + txt.length);\n },\n [engine.visible, engine.handleTextChange]\n );\n\n const handleBlur = useCallback(() => {\n // delay allows dropdown click to fire first\n setTimeout(() => engine.closeSuggestions(), 150);\n }, [engine.closeSuggestions]);\n\n const handleSelect = useCallback(\n (item: unknown) => {\n if (textareaRef.current) {\n engine.selectOption(item, textareaRef.current);\n }\n },\n [engine.selectOption]\n );\n\n const showDropdown = engine.activeTrigger !== null && dropdownPos !== null;\n\n return (\n <div\n className={className}\n style={{ position: \"relative\" }}\n data-mentionize-container=\"\"\n >\n <MentionHighlighter\n visible={engine.visible}\n mentions={engine.mentions}\n triggers={triggers}\n textareaRef={textareaRef}\n className={highlighterClassName}\n style={SHARED_STYLE}\n />\n\n <textarea\n ref={textareaRef}\n value={engine.visible}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={handleBlur}\n rows={rows}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n aria-autocomplete=\"list\"\n aria-expanded={showDropdown}\n className={inputClassName}\n style={{\n ...SHARED_STYLE,\n position: \"relative\",\n width: \"100%\",\n resize: \"vertical\",\n background: \"transparent\",\n color: \"transparent\",\n caretColor: \"CanvasText\",\n zIndex: 10,\n }}\n data-mentionize-input=\"\"\n />\n\n {/* Caret mirror div */}\n <div\n ref={mirrorRef}\n aria-hidden\n style={{\n position: \"absolute\",\n top: 0,\n left: -9999,\n visibility: \"hidden\",\n ...SHARED_STYLE,\n }}\n data-mentionize-mirror=\"\"\n />\n\n {showDropdown && engine.activeTrigger && (\n renderDropdown ? (\n renderDropdown({\n items: engine.filteredOptions,\n highlightedIndex: engine.highlightIndex,\n onSelect: handleSelect,\n onHighlight: engine.setHighlightIndex,\n loading: engine.searchLoading,\n onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,\n })\n ) : (\n <MentionDropdown\n items={engine.filteredOptions}\n trigger={engine.activeTrigger.trigger}\n highlightedIndex={engine.highlightIndex}\n onHighlight={engine.setHighlightIndex}\n onSelect={handleSelect}\n onLoadMore={engine.searchHasMore ? engine.loadMore : undefined}\n loading={engine.searchLoading}\n position={dropdownPos}\n width={dropdownWidth}\n className={dropdownClassName}\n />\n )\n )}\n </div>\n );\n }\n);\n\nMentionInput.displayName = \"MentionInput\";\n",
6
- "import React, { useCallback, useEffect, useRef } from \"react\";\nimport type { CaretPosition, MentionTrigger } from \"./types.ts\";\n\ninterface MentionDropdownProps {\n items: unknown[];\n trigger: MentionTrigger<any>;\n highlightedIndex: number;\n onHighlight: (index: number) => void;\n onSelect: (item: unknown) => void;\n onLoadMore?: () => void;\n loading: boolean;\n position: CaretPosition;\n width: number;\n className?: string;\n}\n\nexport const MentionDropdown: React.FC<MentionDropdownProps> = ({\n items,\n trigger,\n highlightedIndex,\n onHighlight,\n onSelect,\n onLoadMore,\n loading,\n position,\n width,\n className,\n}) => {\n const listRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // IntersectionObserver for infinite scroll\n useEffect(() => {\n if (!onLoadMore || !sentinelRef.current) return;\n const sentinel = sentinelRef.current;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n onLoadMore();\n }\n },\n { root: listRef.current, threshold: 0.1 }\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [onLoadMore]);\n\n // Ensure highlighted item is visible\n useEffect(() => {\n const container = listRef.current;\n if (!container) return;\n const highlighted = container.querySelector(\n `[data-mentionize-option-index=\"${highlightedIndex}\"]`\n ) as HTMLElement | null;\n if (highlighted) {\n highlighted.scrollIntoView({ block: \"nearest\" });\n }\n }, [highlightedIndex]);\n\n // flip above if near bottom of viewport\n const maxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - position.top - gap;\n const flipAbove = spaceBelow < maxHeight && position.top > maxHeight;\n\n const style: React.CSSProperties = {\n position: \"fixed\",\n width,\n maxHeight,\n overflowY: \"auto\",\n zIndex: 50,\n ...(flipAbove\n ? { bottom: window.innerHeight - position.top + gap, left: position.left }\n : { top: position.top + gap, left: position.left }),\n };\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault(); // prevent blur of input\n }, []);\n\n if (!items.length && !loading) return null;\n\n return (\n <div\n ref={listRef}\n role=\"listbox\"\n className={className}\n style={style}\n data-mentionize-dropdown=\"\"\n onMouseDown={handleMouseDown}\n >\n {items.map((item, i) => {\n const isHighlighted = i === highlightedIndex;\n\n if (trigger.renderOption) {\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n data-mentionize-option-index={i}\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.renderOption(item, isHighlighted)}\n </div>\n );\n }\n\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n data-mentionize-option-index={i}\n data-mentionize-option=\"\"\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.displayText(item)}\n </div>\n );\n })}\n {loading && (\n <div data-mentionize-loading=\"\">Loading...</div>\n )}\n {onLoadMore && !loading && (\n <div ref={sentinelRef} style={{ height: 1 }} aria-hidden />\n )}\n </div>\n );\n};\n",
7
- "import React, { useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\n\ninterface MentionHighlighterProps {\n visible: string;\n mentions: ActiveMention[];\n triggers: MentionTrigger<any>[];\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Split a string so that newlines become <br/> elements */\nfunction textToNodes(text: string): React.ReactNode[] {\n const parts = text.split(\"\\n\");\n const nodes: React.ReactNode[] = [];\n for (let i = 0; i < parts.length; i++) {\n if (i > 0) nodes.push(React.createElement(\"br\", { key: `br-${i}` }));\n if (parts[i]) nodes.push(parts[i]);\n }\n return nodes;\n}\n\nexport const MentionHighlighter: React.FC<MentionHighlighterProps> = ({\n visible,\n mentions,\n triggers,\n textareaRef,\n className,\n style,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n\n // Sync scroll with textarea\n useEffect(() => {\n const textarea = textareaRef.current;\n const highlighter = ref.current;\n if (!textarea || !highlighter) return;\n\n const onScroll = () => {\n highlighter.scrollTop = textarea.scrollTop;\n highlighter.scrollLeft = textarea.scrollLeft;\n };\n\n textarea.addEventListener(\"scroll\", onScroll);\n return () => textarea.removeEventListener(\"scroll\", onScroll);\n }, [textareaRef]);\n\n const children = useMemo(() => {\n const sorted = mentions.slice().sort((a, b) => a.start - b.start);\n if (!sorted.length) return textToNodes(visible);\n\n const classMap = new Map<string, string>();\n for (const t of triggers) {\n classMap.set(t.trigger, t.mentionClassName ?? \"mentionize-mention\");\n }\n\n const nodes: React.ReactNode[] = [];\n let last = 0;\n for (let i = 0; i < sorted.length; i++) {\n const m = sorted[i]!;\n // Text before this mention\n if (last < m.start) {\n nodes.push(...textToNodes(visible.slice(last, m.start)));\n }\n\n const mentionText = visible.slice(m.start, m.end);\n const cls = classMap.get(m.trigger) ?? \"mentionize-mention\";\n nodes.push(\n React.createElement(\n \"span\",\n {\n key: `mention-${i}`,\n className: cls,\n \"data-mentionize-trigger\": m.trigger,\n \"data-mentionize-key\": m.key,\n },\n mentionText\n )\n );\n last = m.end;\n }\n // after last mention\n if (last < visible.length) {\n nodes.push(...textToNodes(visible.slice(last)));\n }\n return nodes;\n }, [visible, mentions, triggers]);\n\n // After render, neutralize horizontal box-model impact of mention spans\n // so user-applied padding/border/margin don't shift overlay text relative to the textarea.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const spans = el.querySelectorAll<HTMLElement>(\"[data-mentionize-trigger]\");\n for (let i = 0; i < spans.length; i++) {\n const span = spans[i]!;\n // Reset any previous compensation before measuring\n span.style.marginLeft = \"\";\n span.style.marginRight = \"\";\n const cs = getComputedStyle(span);\n const extraLeft =\n parseFloat(cs.paddingLeft) +\n parseFloat(cs.borderLeftWidth) +\n parseFloat(cs.marginLeft);\n const extraRight =\n parseFloat(cs.paddingRight) +\n parseFloat(cs.borderRightWidth) +\n parseFloat(cs.marginRight);\n if (extraLeft) span.style.marginLeft = `${-extraLeft}px`;\n if (extraRight) span.style.marginRight = `${-extraRight}px`;\n }\n });\n\n return React.createElement(\n \"div\",\n {\n ref,\n className,\n style: {\n position: \"absolute\" as const,\n inset: 0,\n pointerEvents: \"none\" as const,\n overflow: \"auto\",\n ...style,\n },\n \"aria-hidden\": true,\n \"data-mentionize-highlighter\": \"\",\n },\n ...children\n );\n};\n",
5
+ "import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { MentionDropdown } from \"./MentionDropdown.tsx\";\nimport { MentionHighlighter } from \"./MentionHighlighter.tsx\";\nimport type { CaretPosition, MentionInputProps } from \"./types.ts\";\nimport { useCaretPosition } from \"./useCaretPosition.ts\";\nimport { useMentionEngine } from \"./useMentionEngine.ts\";\n\nconst SHARED_STYLE: React.CSSProperties = {\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"anywhere\",\n wordBreak: \"break-word\",\n padding: \"0.5rem 0.75rem\",\n fontFamily: \"inherit\",\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n letterSpacing: \"normal\",\n boxSizing: \"border-box\",\n};\n\nexport const MentionInput = forwardRef<HTMLTextAreaElement, MentionInputProps>(\n (\n {\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n placeholder,\n disabled,\n rows = 4,\n className,\n inputClassName,\n highlighterClassName,\n dropdownClassName,\n dropdownWidth = 250,\n loadingText,\n renderDropdown,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedBy,\n },\n ref\n ) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n useImperativeHandle(ref, () => textareaRef.current!);\n\n const engine = useMentionEngine({\n triggers,\n value,\n defaultValue,\n onChange,\n onMentionsChange,\n });\n\n // Restore caret position after render, then clear so we don't\n // fight the browser on subsequent renders (like arrow-key navigation)\n useLayoutEffect(() => {\n const pos = engine.caretPosRef.current;\n const ta = textareaRef.current;\n if (pos !== null && ta && document.activeElement === ta) {\n ta.setSelectionRange(pos, pos);\n engine.caretPosRef.current = null;\n }\n });\n\n const { mirrorRef, getCaretPosition } = useCaretPosition(dropdownWidth);\n const [dropdownPos, setDropdownPos] = useState<CaretPosition | null>(null);\n\n // Update dropdown position when active trigger changes\n useEffect(() => {\n if (engine.activeTrigger && textareaRef.current) {\n requestAnimationFrame(() => {\n const pos = getCaretPosition(textareaRef.current!);\n if (pos) setDropdownPos(pos);\n });\n } else {\n setDropdownPos(null);\n }\n }, [engine.activeTrigger, engine.visible, getCaretPosition]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n engine.handleTextChange(e.target.value, e.target.selectionStart);\n },\n [engine.handleTextChange]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (textareaRef.current) {\n engine.handleKeyDown(e, textareaRef.current);\n }\n },\n [engine.handleKeyDown]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const ta = textareaRef.current;\n if (!ta) return;\n const txt = e.clipboardData.getData(\"text\");\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const newText =\n engine.visible.slice(0, start) + txt + engine.visible.slice(end);\n e.preventDefault();\n engine.handleTextChange(newText, start + txt.length);\n },\n [engine.visible, engine.handleTextChange]\n );\n\n const handleBlur = useCallback(() => {\n // delay allows dropdown click to fire first\n setTimeout(() => engine.closeSuggestions(), 150);\n }, [engine.closeSuggestions]);\n\n const handleSelect = useCallback(\n (item: unknown) => {\n if (textareaRef.current) {\n engine.selectOption(item, textareaRef.current);\n }\n },\n [engine.selectOption]\n );\n\n const showDropdown = engine.activeTrigger !== null && dropdownPos !== null;\n\n return (\n <div\n className={className}\n style={{ position: \"relative\" }}\n data-mentionize-container=\"\"\n >\n <MentionHighlighter\n visible={engine.visible}\n mentions={engine.mentions}\n triggers={triggers}\n textareaRef={textareaRef}\n getItemForMention={engine.getItemForMention}\n className={highlighterClassName}\n style={SHARED_STYLE}\n />\n\n <textarea\n ref={textareaRef}\n value={engine.visible}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={handleBlur}\n rows={rows}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n aria-autocomplete=\"list\"\n aria-expanded={showDropdown}\n className={inputClassName}\n style={{\n ...SHARED_STYLE,\n position: \"relative\",\n width: \"100%\",\n resize: \"vertical\",\n background: \"transparent\",\n color: \"transparent\",\n caretColor: \"CanvasText\",\n zIndex: 10,\n }}\n data-mentionize-input=\"\"\n />\n\n {/* Caret mirror div */}\n <div\n ref={mirrorRef}\n aria-hidden\n style={{\n position: \"absolute\",\n top: 0,\n left: -9999,\n visibility: \"hidden\",\n ...SHARED_STYLE,\n }}\n data-mentionize-mirror=\"\"\n />\n\n {showDropdown && engine.activeTrigger && (\n renderDropdown ? (\n renderDropdown({\n items: engine.filteredOptions,\n highlightedIndex: engine.highlightIndex,\n onSelect: handleSelect,\n onHighlight: engine.setHighlightIndex,\n loading: engine.searchLoading,\n onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,\n })\n ) : (\n <MentionDropdown\n items={engine.filteredOptions}\n trigger={engine.activeTrigger.trigger}\n highlightedIndex={engine.highlightIndex}\n onHighlight={engine.setHighlightIndex}\n onSelect={handleSelect}\n onLoadMore={engine.searchHasMore ? engine.loadMore : undefined}\n loading={engine.searchLoading}\n loadingText={loadingText}\n position={dropdownPos}\n width={dropdownWidth}\n className={dropdownClassName}\n />\n )\n )}\n </div>\n );\n }\n);\n\nMentionInput.displayName = \"MentionInput\";\n",
6
+ "import React, { useCallback, useEffect, useRef } from \"react\";\nimport type { CaretPosition, MentionTrigger } from \"./types.ts\";\n\ninterface MentionDropdownProps {\n items: unknown[];\n trigger: MentionTrigger<any>;\n highlightedIndex: number;\n onHighlight: (index: number) => void;\n onSelect: (item: unknown) => void;\n onLoadMore?: () => void;\n loading: boolean;\n loadingText?: string;\n position: CaretPosition;\n width: number;\n className?: string;\n}\n\nexport const MentionDropdown: React.FC<MentionDropdownProps> = ({\n items,\n trigger,\n highlightedIndex,\n onHighlight,\n onSelect,\n onLoadMore,\n loading,\n loadingText,\n position,\n width,\n className,\n}) => {\n const listRef = useRef<HTMLDivElement>(null);\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // IntersectionObserver for infinite scroll\n useEffect(() => {\n if (!onLoadMore || !sentinelRef.current) return;\n const sentinel = sentinelRef.current;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n onLoadMore();\n }\n },\n { root: listRef.current, threshold: 0.1 }\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [onLoadMore]);\n\n // Ensure highlighted item is visible\n useEffect(() => {\n const container = listRef.current;\n if (!container) return;\n const highlighted = container.querySelector(\n `[data-mentionize-option-index=\"${highlightedIndex}\"]`\n ) as HTMLElement | null;\n if (highlighted) {\n highlighted.scrollIntoView({ block: \"nearest\" });\n }\n }, [highlightedIndex]);\n\n // flip above if near bottom of viewport\n const maxHeight = 240;\n const gap = 4;\n const spaceBelow = window.innerHeight - position.top - gap;\n const flipAbove = spaceBelow < maxHeight && position.top > maxHeight;\n\n const style: React.CSSProperties = {\n position: \"fixed\",\n width,\n maxHeight,\n overflowY: \"auto\",\n zIndex: 50,\n ...(flipAbove\n ? { bottom: window.innerHeight - position.top + gap, left: position.left }\n : { top: position.top + gap, left: position.left }),\n };\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault(); // prevent blur of input\n }, []);\n\n if (!items.length && !loading) return null;\n\n return (\n <div\n ref={listRef}\n role=\"listbox\"\n className={className}\n style={style}\n data-mentionize-dropdown=\"\"\n onMouseDown={handleMouseDown}\n >\n {items.map((item, i) => {\n const isHighlighted = i === highlightedIndex;\n const optCls = typeof trigger.optionClassName === \"function\"\n ? trigger.optionClassName(item)\n : trigger.optionClassName;\n\n if (trigger.renderOption) {\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n className={optCls}\n data-mentionize-option-index={i}\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.renderOption(item, isHighlighted)}\n </div>\n );\n }\n\n return (\n <div\n key={i}\n role=\"option\"\n aria-selected={isHighlighted}\n className={optCls}\n data-mentionize-option-index={i}\n data-mentionize-option=\"\"\n data-mentionize-option-highlighted={isHighlighted || undefined}\n onMouseEnter={() => onHighlight(i)}\n onClick={() => onSelect(item)}\n >\n {trigger.displayText(item)}\n </div>\n );\n })}\n {loading && (\n <div data-mentionize-loading=\"\">{loadingText ?? \"Loading...\"}</div>\n )}\n {onLoadMore && !loading && (\n <div ref={sentinelRef} style={{ height: 1 }} aria-hidden />\n )}\n </div>\n );\n};\n",
7
+ "import React, { useEffect, useLayoutEffect, useMemo, useRef } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\n\ninterface MentionHighlighterProps {\n visible: string;\n mentions: ActiveMention[];\n triggers: MentionTrigger<any>[];\n textareaRef: React.RefObject<HTMLTextAreaElement | null>;\n getItemForMention?: (triggerChar: string, key: string) => unknown;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Split a string so that newlines become <br/> elements */\nfunction textToNodes(text: string): React.ReactNode[] {\n const parts = text.split(\"\\n\");\n const nodes: React.ReactNode[] = [];\n for (let i = 0; i < parts.length; i++) {\n if (i > 0) nodes.push(React.createElement(\"br\", { key: `br-${i}` }));\n if (parts[i]) nodes.push(parts[i]);\n }\n return nodes;\n}\n\nexport const MentionHighlighter: React.FC<MentionHighlighterProps> = ({\n visible,\n mentions,\n triggers,\n textareaRef,\n getItemForMention,\n className,\n style,\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n\n // Sync scroll with textarea\n useEffect(() => {\n const textarea = textareaRef.current;\n const highlighter = ref.current;\n if (!textarea || !highlighter) return;\n\n const onScroll = () => {\n highlighter.scrollTop = textarea.scrollTop;\n highlighter.scrollLeft = textarea.scrollLeft;\n };\n\n textarea.addEventListener(\"scroll\", onScroll);\n return () => textarea.removeEventListener(\"scroll\", onScroll);\n }, [textareaRef]);\n\n const children = useMemo(() => {\n const sorted = mentions.slice().sort((a, b) => a.start - b.start);\n if (!sorted.length) return textToNodes(visible);\n\n const triggerMap = new Map<string, MentionTrigger<any>>();\n for (const t of triggers) {\n triggerMap.set(t.trigger, t);\n }\n\n const nodes: React.ReactNode[] = [];\n let last = 0;\n for (let i = 0; i < sorted.length; i++) {\n const m = sorted[i]!;\n // Text before this mention\n if (last < m.start) {\n nodes.push(...textToNodes(visible.slice(last, m.start)));\n }\n\n const mentionText = visible.slice(m.start, m.end);\n const t = triggerMap.get(m.trigger);\n let cls = \"mentionize-mention\";\n if (t) {\n if (typeof t.mentionClassName === \"function\") {\n const item = getItemForMention?.(m.trigger, m.key) ?? null;\n cls = t.mentionClassName({\n key: m.key,\n displayText: m.displayText,\n trigger: m.trigger,\n item,\n });\n } else if (t.mentionClassName) {\n cls = t.mentionClassName;\n }\n }\n nodes.push(\n React.createElement(\n \"span\",\n {\n key: `mention-${i}`,\n className: cls,\n \"data-mentionize-trigger\": m.trigger,\n \"data-mentionize-key\": m.key,\n },\n mentionText\n )\n );\n last = m.end;\n }\n // after last mention\n if (last < visible.length) {\n nodes.push(...textToNodes(visible.slice(last)));\n }\n return nodes;\n }, [visible, mentions, triggers, getItemForMention]);\n\n // After render, neutralize horizontal box-model impact of mention spans\n // so user-applied padding/border/margin don't shift overlay text relative to the textarea.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const spans = el.querySelectorAll<HTMLElement>(\"[data-mentionize-trigger]\");\n for (let i = 0; i < spans.length; i++) {\n const span = spans[i]!;\n // Reset any previous compensation before measuring\n span.style.marginLeft = \"\";\n span.style.marginRight = \"\";\n const cs = getComputedStyle(span);\n const extraLeft =\n parseFloat(cs.paddingLeft) +\n parseFloat(cs.borderLeftWidth) +\n parseFloat(cs.marginLeft);\n const extraRight =\n parseFloat(cs.paddingRight) +\n parseFloat(cs.borderRightWidth) +\n parseFloat(cs.marginRight);\n if (extraLeft) span.style.marginLeft = `${-extraLeft}px`;\n if (extraRight) span.style.marginRight = `${-extraRight}px`;\n }\n });\n\n return React.createElement(\n \"div\",\n {\n ref,\n className,\n style: {\n position: \"absolute\" as const,\n inset: 0,\n pointerEvents: \"none\" as const,\n overflow: \"auto\",\n ...style,\n },\n \"aria-hidden\": true,\n \"data-mentionize-highlighter\": \"\",\n },\n ...children\n );\n};\n",
8
8
  "import { useCallback, useRef } from \"react\";\nimport type { CaretPosition } from \"./types.ts\";\n\nconst SHARED_STYLE_PROPS = [\n \"whiteSpace\",\n \"overflowWrap\",\n \"wordBreak\",\n \"padding\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"lineHeight\",\n \"letterSpacing\",\n \"tabSize\",\n \"boxSizing\",\n \"borderWidth\",\n \"borderStyle\",\n] as const;\n\nexport function useCaretPosition(dropdownWidth: number) {\n const mirrorRef = useRef<HTMLDivElement>(null);\n\n const getCaretPosition = useCallback(\n (\n textarea: HTMLTextAreaElement,\n caretIndex?: number,\n textOverride?: string\n ): CaretPosition | null => {\n const mirror = mirrorRef.current;\n if (!mirror) return null;\n\n const caret = caretIndex ?? textarea.selectionStart;\n const source = textOverride ?? textarea.value;\n const before = source.slice(0, caret);\n\n // Copy textarea computed styles to mirror\n const computed = getComputedStyle(textarea);\n for (const prop of SHARED_STYLE_PROPS) {\n (mirror.style as any)[prop] = (computed as any)[prop];\n }\n mirror.style.width = `${textarea.offsetWidth}px`;\n\n mirror.textContent = before;\n\n const span = document.createElement(\"span\");\n span.textContent = \"\\u200b\";\n mirror.appendChild(span);\n mirror.scrollTop = textarea.scrollTop;\n\n const spanRect = span.getBoundingClientRect();\n const mirrorRect = mirror.getBoundingClientRect();\n const textareaRect = textarea.getBoundingClientRect();\n\n const top =\n textareaRect.top +\n (spanRect.top - mirrorRect.top) -\n textarea.scrollTop +\n span.offsetHeight;\n let left = textareaRect.left + (spanRect.left - mirrorRect.left);\n\n // Clamp to viewport\n if (left + dropdownWidth > window.innerWidth - 8) {\n left = window.innerWidth - dropdownWidth - 8;\n }\n if (left < 8) left = 8;\n\n mirror.innerHTML = \"\";\n\n return {\n top: Math.min(Math.max(top, 8), window.innerHeight - 8),\n left,\n };\n },\n [dropdownWidth]\n );\n\n return { mirrorRef, getCaretPosition };\n}\n",
9
- "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\nimport { escapeRegex } from \"./utils.ts\";\n\ninterface ActiveTriggerState {\n trigger: MentionTrigger<any>;\n query: string;\n startPos: number; // where the trigger character is in the visible text\n}\n\ninterface SearchState {\n items: unknown[];\n page: number;\n hasMore: boolean;\n loading: boolean;\n}\n\ninterface MentionEngineOptions {\n triggers: MentionTrigger<any>[];\n value?: string;\n defaultValue?: string;\n onChange?: (raw: string) => void;\n onMentionsChange?: (mentions: ActiveMention[]) => void;\n}\n\n// Detect mentions in visible text\nfunction detectMentionsInText(\n visibleText: string,\n triggers: MentionTrigger<any>[],\n getCache: (triggerChar: string) => Map<string, unknown>,\n): ActiveMention[] {\n const all: ActiveMention[] = [];\n\n for (const t of triggers) {\n const triggerChar = t.trigger;\n if (!visibleText.includes(triggerChar)) continue;\n\n const cache = getCache(triggerChar);\n const knownItems: { displayText: string; key: string; item: unknown }[] =\n [];\n\n if (t.options) {\n for (const item of t.options) {\n knownItems.push({\n displayText: t.displayText(item),\n key: getItemKey(t, item),\n item,\n });\n }\n }\n\n for (const [key, item] of cache.entries()) {\n if (item !== null) {\n const dt = t.displayText(item);\n if (!knownItems.some((k) => k.key === key)) {\n knownItems.push({ displayText: dt, key, item });\n }\n }\n }\n\n if (!knownItems.length) continue;\n\n const compiled = knownItems.map((ki) => {\n const pat = \"^\" + escapeRegex(ki.displayText).replace(/\\s+/g, \"\\\\s+\");\n return { ...ki, re: new RegExp(pat, \"i\") };\n });\n\n const positions: number[] = [];\n let idx = visibleText.indexOf(triggerChar);\n while (idx !== -1) {\n positions.push(idx);\n idx = visibleText.indexOf(triggerChar, idx + 1);\n }\n\n const candidates: ActiveMention[] = [];\n for (const pos of positions) {\n const after = visibleText.slice(pos + triggerChar.length);\n for (const c of compiled) {\n const match = c.re.exec(after);\n if (!match) continue;\n const matched = match[0];\n const end = pos + triggerChar.length + matched.length;\n const next = visibleText[end];\n if (next && !/[\\s,.:;!?)}\\]]/.test(next)) continue;\n candidates.push({\n trigger: triggerChar,\n displayText: matched,\n key: c.key,\n start: pos,\n end,\n });\n }\n }\n\n candidates.sort((a, b) =>\n a.start !== b.start\n ? a.start - b.start\n : b.end - b.start - (a.end - a.start),\n );\n for (const c of candidates) {\n const overlaps = all.some(\n (f) => Math.max(f.start, c.start) < Math.min(f.end, c.end),\n );\n if (!overlaps) all.push(c);\n }\n }\n\n return all;\n}\n\n// Shallow-compare two mention arrays\nfunction mentionsEqual(a: ActiveMention[], b: ActiveMention[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n if (ai.start !== bi.start || ai.end !== bi.end || ai.key !== bi.key)\n return false;\n }\n return true;\n}\n\nexport function useMentionEngine(options: MentionEngineOptions) {\n const {\n triggers,\n value: controlledValue,\n defaultValue,\n onChange,\n onMentionsChange,\n } = options;\n\n const lastRawRef = useRef(controlledValue ?? defaultValue ?? \"\");\n const suppressEmitRef = useRef(false);\n const caretPosRef = useRef<number | null>(null);\n const prevMentionsRef = useRef<ActiveMention[]>([]);\n\n // Known items cache\n const cacheRef = useRef<Map<string, Map<string, unknown>>>(new Map());\n\n function getCache(triggerChar: string): Map<string, unknown> {\n let map = cacheRef.current.get(triggerChar);\n if (!map) {\n map = new Map();\n cacheRef.current.set(triggerChar, map);\n }\n return map;\n }\n\n // Populate cache from static options\n useEffect(() => {\n for (const t of triggers) {\n if (t.options) {\n const cache = getCache(t.trigger);\n for (const item of t.options) {\n const serialized = t.serialize(item);\n // Extract key by running pattern on the serialized form\n const re = new RegExp(\n t.pattern.source,\n t.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n const { key } = t.parseMatch(m);\n cache.set(key, item);\n }\n }\n }\n }\n }, [triggers]);\n\n // Convert raw to visible text\n const rawToVisible = useCallback(\n (raw: string): string => {\n let result = raw;\n for (const t of triggers) {\n const globalRe = new RegExp(\n t.pattern.source,\n t.pattern.flags.includes(\"g\")\n ? t.pattern.flags\n : t.pattern.flags + \"g\",\n );\n const parts: string[] = [];\n let lastIndex = 0;\n let m: RegExpExecArray | null;\n globalRe.lastIndex = 0;\n while ((m = globalRe.exec(result)) !== null) {\n parts.push(result.slice(lastIndex, m.index));\n const parsed = t.parseMatch(m);\n // Cache the item data from the match\n const cache = getCache(t.trigger);\n // placeholder for unmatched items\n if (!cache.has(parsed.key)) {\n cache.set(parsed.key, null);\n }\n parts.push(t.trigger + parsed.displayText);\n lastIndex = m.index + m[0].length;\n if (!t.pattern.flags.includes(\"g\")) break;\n }\n parts.push(result.slice(lastIndex));\n result = parts.join(\"\");\n }\n return result;\n },\n [triggers],\n );\n\n // Initialize visible text from raw\n const [visible, setVisible] = useState<string>(() =>\n rawToVisible(controlledValue ?? defaultValue ?? \"\"),\n );\n\n // Detect mentions in visible text\n const mentions: ActiveMention[] = useMemo(() => {\n const newMentions = detectMentionsInText(visible, triggers, getCache);\n if (mentionsEqual(prevMentionsRef.current, newMentions)) {\n return prevMentionsRef.current;\n }\n prevMentionsRef.current = newMentions;\n return newMentions;\n }, [visible, triggers]);\n\n // Build raw value from visible + mentions\n const visibleToRaw = useCallback(\n (vis: string, mentionsList: ActiveMention[]): string => {\n if (!mentionsList.length) return vis;\n const ordered = mentionsList.slice().sort((a, b) => a.start - b.start);\n let raw = \"\";\n let last = 0;\n for (const m of ordered) {\n raw += vis.slice(last, m.start);\n // Find the trigger config and the cached item\n const t = triggers.find((tr) => tr.trigger === m.trigger);\n if (t) {\n const cache = getCache(t.trigger);\n const item = cache.get(m.key);\n if (item !== null && item !== undefined) {\n raw += t.serialize(item);\n } else {\n raw += vis.slice(m.start, m.end);\n }\n } else {\n raw += vis.slice(m.start, m.end);\n }\n last = m.end;\n }\n raw += vis.slice(last);\n return raw;\n },\n [triggers],\n );\n\n // Synchronously emit raw value + mentions after visible text changes\n const emitSync = useCallback(\n (newVisible: string) => {\n const newMentions = detectMentionsInText(newVisible, triggers, getCache);\n\n if (!mentionsEqual(prevMentionsRef.current, newMentions)) {\n prevMentionsRef.current = newMentions;\n }\n\n const raw = visibleToRaw(newVisible, prevMentionsRef.current);\n if (raw !== lastRawRef.current) {\n lastRawRef.current = raw;\n onChange?.(raw);\n }\n onMentionsChange?.(prevMentionsRef.current);\n },\n [triggers, visibleToRaw, onChange, onMentionsChange],\n );\n\n useEffect(() => {\n if (controlledValue === undefined) return;\n if (controlledValue === lastRawRef.current) return;\n lastRawRef.current = controlledValue;\n suppressEmitRef.current = true;\n setVisible(rawToVisible(controlledValue));\n }, [controlledValue, rawToVisible]);\n\n const [activeTrigger, setActiveTrigger] = useState<ActiveTriggerState | null>(\n null,\n );\n const [searchState, setSearchState] = useState<SearchState>({\n items: [],\n page: 0,\n hasMore: false,\n loading: false,\n });\n const [highlightIndex, setHighlightIndex] = useState(0);\n const searchAbortRef = useRef<AbortController | null>(null);\n\n const detectActiveTrigger = useCallback(\n (text: string, caretPos: number): ActiveTriggerState | null => {\n // Look backwards from caret for any trigger character\n const prefix = text.slice(0, caretPos);\n for (const t of triggers) {\n const triggerChar = t.trigger;\n // Find the last occurrence of trigger char before caret\n const re = new RegExp(\n escapeRegex(triggerChar) +\n \"([^\\\\n\" +\n escapeRegex(triggerChar) +\n \"]*)$\",\n );\n const match = re.exec(prefix);\n if (match && match[1] !== undefined) {\n const query = match[1];\n // Don't activate if query contains whitespace (user moved on)\n if (/\\s/.test(query)) continue;\n return {\n trigger: t,\n query,\n startPos: match.index,\n };\n }\n }\n return null;\n },\n [triggers],\n );\n\n // Get filtered options for current trigger\n const filteredOptions = useMemo(() => {\n if (!activeTrigger) return [];\n const t = activeTrigger.trigger;\n const q = activeTrigger.query.toLowerCase();\n\n if (t.onSearch) {\n // Async mode returns search state items\n return searchState.items;\n }\n\n if (t.options) {\n if (!q) return t.options;\n return t.options.filter((item) =>\n t.displayText(item).toLowerCase().includes(q),\n );\n }\n\n return [];\n }, [activeTrigger, searchState.items]);\n\n useEffect(() => {\n if (!activeTrigger?.trigger.onSearch) return;\n\n const t = activeTrigger.trigger;\n const query = activeTrigger.query;\n\n // Abort previous search\n searchAbortRef.current?.abort();\n const controller = new AbortController();\n searchAbortRef.current = controller;\n\n setSearchState((s) => ({ ...s, loading: true, page: 0 }));\n\n const timer = setTimeout(async () => {\n try {\n const result = await t.onSearch!(query, 0);\n if (controller.signal.aborted) return;\n setSearchState({\n items: result.items,\n page: 0,\n hasMore: result.hasMore,\n loading: false,\n });\n } catch {\n if (controller.signal.aborted) return;\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, 150);\n\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [activeTrigger?.trigger, activeTrigger?.query]);\n\n const loadMore = useCallback(async () => {\n if (\n !activeTrigger?.trigger.onSearch ||\n searchState.loading ||\n !searchState.hasMore\n )\n return;\n\n const t = activeTrigger.trigger;\n const nextPage = searchState.page + 1;\n setSearchState((s) => ({ ...s, loading: true }));\n\n try {\n const result = await t.onSearch!(activeTrigger.query, nextPage);\n setSearchState((s) => ({\n items: [...s.items, ...result.items],\n page: nextPage,\n hasMore: result.hasMore,\n loading: false,\n }));\n } catch {\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, [activeTrigger, searchState]);\n\n // Handle text change from textarea\n const handleTextChange = useCallback(\n (newText: string, caretPos: number) => {\n caretPosRef.current = caretPos;\n setVisible(newText);\n emitSync(newText);\n const detected = detectActiveTrigger(newText, caretPos);\n if (detected) {\n setActiveTrigger(detected);\n setHighlightIndex(0);\n } else {\n setActiveTrigger(null);\n }\n },\n [detectActiveTrigger, emitSync],\n );\n\n // Select an option from the dropdown\n const selectOption = useCallback(\n (item: unknown, textarea: HTMLTextAreaElement) => {\n if (!activeTrigger) return;\n const t = activeTrigger.trigger;\n\n // Add to cache\n const cache = getCache(t.trigger);\n const key = getItemKey(t, item);\n cache.set(key, item);\n\n const displayText = t.displayText(item);\n const mentionText = t.trigger + displayText;\n\n const before = visible.slice(0, activeTrigger.startPos);\n const after = visible.slice(textarea.selectionStart);\n const newVis = before + mentionText + \" \" + after;\n\n const pos = before.length + mentionText.length + 1;\n caretPosRef.current = pos;\n setVisible(newVis);\n emitSync(newVis);\n setActiveTrigger(null);\n },\n [activeTrigger, visible, emitSync],\n );\n\n const closeSuggestions = useCallback(() => {\n setActiveTrigger(null);\n setSearchState({ items: [], page: 0, hasMore: false, loading: false });\n }, []);\n\n // Keyboard handling\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, textarea: HTMLTextAreaElement): boolean => {\n if (!activeTrigger) return false;\n\n const len = filteredOptions.length;\n if (!len && !searchState.loading) return false;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n const next = (highlightIndex + 1) % Math.max(len, 1);\n setHighlightIndex(next);\n // Trigger load more near end\n if (\n len - 1 - next <= 3 &&\n searchState.hasMore &&\n !searchState.loading\n ) {\n loadMore();\n }\n return true;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setHighlightIndex(\n (highlightIndex - 1 + Math.max(len, 1)) % Math.max(len, 1),\n );\n return true;\n }\n if (e.key === \"Enter\") {\n e.preventDefault();\n const item = filteredOptions[highlightIndex];\n if (item) selectOption(item, textarea);\n return true;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n closeSuggestions();\n return true;\n }\n return false;\n },\n [\n activeTrigger,\n filteredOptions,\n highlightIndex,\n searchState,\n selectOption,\n closeSuggestions,\n loadMore,\n ],\n );\n\n return {\n visible,\n setVisible,\n mentions,\n activeTrigger,\n filteredOptions,\n highlightIndex,\n setHighlightIndex,\n searchLoading: searchState.loading,\n searchHasMore: searchState.hasMore,\n handleTextChange,\n handleKeyDown,\n selectOption,\n closeSuggestions,\n loadMore,\n rawToVisible,\n visibleToRaw,\n caretPosRef,\n };\n}\n\nfunction getItemKey(trigger: MentionTrigger<any>, item: unknown): string {\n const serialized = trigger.serialize(item);\n const re = new RegExp(\n trigger.pattern.source,\n trigger.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n return trigger.parseMatch(m).key;\n }\n return serialized;\n}\n",
9
+ "import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ActiveMention, MentionTrigger } from \"./types.ts\";\nimport { escapeRegex } from \"./utils.ts\";\n\ninterface ActiveTriggerState {\n trigger: MentionTrigger<any>;\n query: string;\n startPos: number; // where the trigger character is in the visible text\n}\n\ninterface SearchState {\n items: unknown[];\n page: number;\n hasMore: boolean;\n loading: boolean;\n}\n\ninterface MentionEngineOptions {\n triggers: MentionTrigger<any>[];\n value?: string;\n defaultValue?: string;\n onChange?: (raw: string) => void;\n onMentionsChange?: (mentions: ActiveMention[]) => void;\n}\n\n// Detect mentions in visible text\nfunction detectMentionsInText(\n visibleText: string,\n triggers: MentionTrigger<any>[],\n getCache: (triggerChar: string) => Map<string, unknown>,\n): ActiveMention[] {\n const all: ActiveMention[] = [];\n\n for (const t of triggers) {\n const triggerChar = t.trigger;\n if (!visibleText.includes(triggerChar)) continue;\n\n const cache = getCache(triggerChar);\n const knownItems: { displayText: string; key: string; item: unknown }[] =\n [];\n\n if (t.options) {\n for (const item of t.options) {\n knownItems.push({\n displayText: t.displayText(item),\n key: getItemKey(t, item),\n item,\n });\n }\n }\n\n for (const [key, item] of cache.entries()) {\n if (item !== null) {\n const dt = t.displayText(item);\n if (!knownItems.some((k) => k.key === key)) {\n knownItems.push({ displayText: dt, key, item });\n }\n }\n }\n\n if (!knownItems.length) continue;\n\n const compiled = knownItems.map((ki) => {\n const pat = \"^\" + escapeRegex(ki.displayText).replace(/\\s+/g, \"\\\\s+\");\n return { ...ki, re: new RegExp(pat, \"i\") };\n });\n\n const positions: number[] = [];\n let idx = visibleText.indexOf(triggerChar);\n while (idx !== -1) {\n positions.push(idx);\n idx = visibleText.indexOf(triggerChar, idx + 1);\n }\n\n const candidates: ActiveMention[] = [];\n for (const pos of positions) {\n const after = visibleText.slice(pos + triggerChar.length);\n for (const c of compiled) {\n const match = c.re.exec(after);\n if (!match) continue;\n const matched = match[0];\n const end = pos + triggerChar.length + matched.length;\n const next = visibleText[end];\n if (next && !/[\\s,.:;!?)}\\]]/.test(next)) continue;\n candidates.push({\n trigger: triggerChar,\n displayText: matched,\n key: c.key,\n start: pos,\n end,\n });\n }\n }\n\n candidates.sort((a, b) =>\n a.start !== b.start\n ? a.start - b.start\n : b.end - b.start - (a.end - a.start),\n );\n for (const c of candidates) {\n const overlaps = all.some(\n (f) => Math.max(f.start, c.start) < Math.min(f.end, c.end),\n );\n if (!overlaps) all.push(c);\n }\n }\n\n return all;\n}\n\n// Shallow-compare two mention arrays\nfunction mentionsEqual(a: ActiveMention[], b: ActiveMention[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n if (ai.start !== bi.start || ai.end !== bi.end || ai.key !== bi.key)\n return false;\n }\n return true;\n}\n\nexport function useMentionEngine(options: MentionEngineOptions) {\n const {\n triggers,\n value: controlledValue,\n defaultValue,\n onChange,\n onMentionsChange,\n } = options;\n\n const lastRawRef = useRef(controlledValue ?? defaultValue ?? \"\");\n const suppressEmitRef = useRef(false);\n const caretPosRef = useRef<number | null>(null);\n const prevMentionsRef = useRef<ActiveMention[]>([]);\n\n // Known items cache\n const cacheRef = useRef<Map<string, Map<string, unknown>>>(new Map());\n\n function getCache(triggerChar: string): Map<string, unknown> {\n let map = cacheRef.current.get(triggerChar);\n if (!map) {\n map = new Map();\n cacheRef.current.set(triggerChar, map);\n }\n return map;\n }\n\n // Populate cache from static options\n useEffect(() => {\n for (const t of triggers) {\n if (t.options) {\n const cache = getCache(t.trigger);\n for (const item of t.options) {\n const serialized = t.serialize(item);\n // Extract key by running pattern on the serialized form\n const re = new RegExp(\n t.pattern.source,\n t.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n const { key } = t.parseMatch(m);\n cache.set(key, item);\n }\n }\n }\n }\n }, [triggers]);\n\n // Convert raw to visible text\n const rawToVisible = useCallback(\n (raw: string): string => {\n let result = raw;\n for (const t of triggers) {\n const globalRe = new RegExp(\n t.pattern.source,\n t.pattern.flags.includes(\"g\")\n ? t.pattern.flags\n : t.pattern.flags + \"g\",\n );\n const parts: string[] = [];\n let lastIndex = 0;\n let m: RegExpExecArray | null;\n globalRe.lastIndex = 0;\n while ((m = globalRe.exec(result)) !== null) {\n parts.push(result.slice(lastIndex, m.index));\n const parsed = t.parseMatch(m);\n // Cache the item data from the match\n const cache = getCache(t.trigger);\n // placeholder for unmatched items\n if (!cache.has(parsed.key)) {\n cache.set(parsed.key, null);\n }\n parts.push(t.trigger + parsed.displayText);\n lastIndex = m.index + m[0].length;\n if (!t.pattern.flags.includes(\"g\")) break;\n }\n parts.push(result.slice(lastIndex));\n result = parts.join(\"\");\n }\n return result;\n },\n [triggers],\n );\n\n // Initialize visible text from raw\n const [visible, setVisible] = useState<string>(() =>\n rawToVisible(controlledValue ?? defaultValue ?? \"\"),\n );\n\n // Detect mentions in visible text\n const mentions: ActiveMention[] = useMemo(() => {\n const newMentions = detectMentionsInText(visible, triggers, getCache);\n if (mentionsEqual(prevMentionsRef.current, newMentions)) {\n return prevMentionsRef.current;\n }\n prevMentionsRef.current = newMentions;\n return newMentions;\n }, [visible, triggers]);\n\n // Build raw value from visible + mentions\n const visibleToRaw = useCallback(\n (vis: string, mentionsList: ActiveMention[]): string => {\n if (!mentionsList.length) return vis;\n const ordered = mentionsList.slice().sort((a, b) => a.start - b.start);\n let raw = \"\";\n let last = 0;\n for (const m of ordered) {\n raw += vis.slice(last, m.start);\n // Find the trigger config and the cached item\n const t = triggers.find((tr) => tr.trigger === m.trigger);\n if (t) {\n const cache = getCache(t.trigger);\n const item = cache.get(m.key);\n if (item !== null && item !== undefined) {\n raw += t.serialize(item);\n } else {\n raw += vis.slice(m.start, m.end);\n }\n } else {\n raw += vis.slice(m.start, m.end);\n }\n last = m.end;\n }\n raw += vis.slice(last);\n return raw;\n },\n [triggers],\n );\n\n // Synchronously emit raw value + mentions after visible text changes\n const emitSync = useCallback(\n (newVisible: string) => {\n const newMentions = detectMentionsInText(newVisible, triggers, getCache);\n\n if (!mentionsEqual(prevMentionsRef.current, newMentions)) {\n prevMentionsRef.current = newMentions;\n }\n\n const raw = visibleToRaw(newVisible, prevMentionsRef.current);\n if (raw !== lastRawRef.current) {\n lastRawRef.current = raw;\n onChange?.(raw);\n }\n onMentionsChange?.(prevMentionsRef.current);\n },\n [triggers, visibleToRaw, onChange, onMentionsChange],\n );\n\n useEffect(() => {\n if (controlledValue === undefined) return;\n if (controlledValue === lastRawRef.current) return;\n lastRawRef.current = controlledValue;\n suppressEmitRef.current = true;\n setVisible(rawToVisible(controlledValue));\n }, [controlledValue, rawToVisible]);\n\n const [activeTrigger, setActiveTrigger] = useState<ActiveTriggerState | null>(\n null,\n );\n const [searchState, setSearchState] = useState<SearchState>({\n items: [],\n page: 0,\n hasMore: false,\n loading: false,\n });\n const [highlightIndex, setHighlightIndex] = useState(0);\n const searchAbortRef = useRef<AbortController | null>(null);\n\n const detectActiveTrigger = useCallback(\n (text: string, caretPos: number): ActiveTriggerState | null => {\n // Look backwards from caret for any trigger character\n const prefix = text.slice(0, caretPos);\n for (const t of triggers) {\n const triggerChar = t.trigger;\n // Find the last occurrence of trigger char before caret\n const re = new RegExp(\n escapeRegex(triggerChar) +\n \"([^\\\\n\" +\n escapeRegex(triggerChar) +\n \"]*)$\",\n );\n const match = re.exec(prefix);\n if (match && match[1] !== undefined) {\n const query = match[1];\n // Don't activate if query contains whitespace (user moved on)\n if (/\\s/.test(query)) continue;\n return {\n trigger: t,\n query,\n startPos: match.index,\n };\n }\n }\n return null;\n },\n [triggers],\n );\n\n // Get filtered options for current trigger\n const filteredOptions = useMemo(() => {\n if (!activeTrigger) return [];\n const t = activeTrigger.trigger;\n const q = activeTrigger.query.toLowerCase();\n\n if (t.onSearch) {\n // Async mode returns search state items\n return searchState.items;\n }\n\n if (t.options) {\n if (!q) return t.options;\n return t.options.filter((item) =>\n t.displayText(item).toLowerCase().includes(q),\n );\n }\n\n return [];\n }, [activeTrigger, searchState.items]);\n\n useEffect(() => {\n if (!activeTrigger?.trigger.onSearch) return;\n\n const t = activeTrigger.trigger;\n const query = activeTrigger.query;\n\n // Abort previous search\n searchAbortRef.current?.abort();\n const controller = new AbortController();\n searchAbortRef.current = controller;\n\n setSearchState((s) => ({ ...s, loading: true, page: 0 }));\n\n const timer = setTimeout(async () => {\n try {\n const result = await t.onSearch!(query, 0);\n if (controller.signal.aborted) return;\n setSearchState({\n items: result.items,\n page: 0,\n hasMore: result.hasMore,\n loading: false,\n });\n } catch {\n if (controller.signal.aborted) return;\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, 150);\n\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [activeTrigger?.trigger, activeTrigger?.query]);\n\n const loadMore = useCallback(async () => {\n if (\n !activeTrigger?.trigger.onSearch ||\n searchState.loading ||\n !searchState.hasMore\n )\n return;\n\n const t = activeTrigger.trigger;\n const nextPage = searchState.page + 1;\n setSearchState((s) => ({ ...s, loading: true }));\n\n try {\n const result = await t.onSearch!(activeTrigger.query, nextPage);\n setSearchState((s) => ({\n items: [...s.items, ...result.items],\n page: nextPage,\n hasMore: result.hasMore,\n loading: false,\n }));\n } catch {\n setSearchState((s) => ({ ...s, loading: false }));\n }\n }, [activeTrigger, searchState]);\n\n // Handle text change from textarea\n const handleTextChange = useCallback(\n (newText: string, caretPos: number) => {\n caretPosRef.current = caretPos;\n setVisible(newText);\n emitSync(newText);\n const detected = detectActiveTrigger(newText, caretPos);\n if (detected) {\n setActiveTrigger(detected);\n setHighlightIndex(0);\n } else {\n setActiveTrigger(null);\n }\n },\n [detectActiveTrigger, emitSync],\n );\n\n // Look up a cached item for a mention\n const getItemForMention = useCallback(\n (triggerChar: string, key: string): unknown => {\n const cache = getCache(triggerChar);\n return cache.get(key) ?? null;\n },\n [],\n );\n\n // Select an option from the dropdown\n const selectOption = useCallback(\n (item: unknown, textarea: HTMLTextAreaElement) => {\n if (!activeTrigger) return;\n const t = activeTrigger.trigger;\n\n if (t.onSelect) {\n // Action trigger mode: close dropdown, remove trigger+query, call onSelect\n const before = visible.slice(0, activeTrigger.startPos);\n const after = visible.slice(textarea.selectionStart);\n const savedStartPos = activeTrigger.startPos;\n\n setActiveTrigger(null);\n\n const result = t.onSelect(item);\n const applyResult = (value: string | null) => {\n if (value !== null) {\n const newVis = before + value + after;\n const pos = savedStartPos + value.length;\n caretPosRef.current = pos;\n setVisible(newVis);\n emitSync(newVis);\n } else {\n // null = cancel, just remove the trigger+query\n const newVis = before + after;\n caretPosRef.current = savedStartPos;\n setVisible(newVis);\n emitSync(newVis);\n }\n };\n\n if (result instanceof Promise) {\n result.then(applyResult);\n } else {\n applyResult(result);\n }\n return;\n }\n\n // Standard mention mode\n const cache = getCache(t.trigger);\n const key = getItemKey(t, item);\n cache.set(key, item);\n\n const displayText = t.displayText(item);\n const mentionText = t.trigger + displayText;\n\n const before = visible.slice(0, activeTrigger.startPos);\n const after = visible.slice(textarea.selectionStart);\n const newVis = before + mentionText + \" \" + after;\n\n const pos = before.length + mentionText.length + 1;\n caretPosRef.current = pos;\n setVisible(newVis);\n emitSync(newVis);\n setActiveTrigger(null);\n },\n [activeTrigger, visible, emitSync],\n );\n\n const closeSuggestions = useCallback(() => {\n setActiveTrigger(null);\n setSearchState({ items: [], page: 0, hasMore: false, loading: false });\n }, []);\n\n // Keyboard handling\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, textarea: HTMLTextAreaElement): boolean => {\n if (!activeTrigger) return false;\n\n const len = filteredOptions.length;\n if (!len && !searchState.loading) return false;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n const next = (highlightIndex + 1) % Math.max(len, 1);\n setHighlightIndex(next);\n // Trigger load more near end\n if (\n len - 1 - next <= 3 &&\n searchState.hasMore &&\n !searchState.loading\n ) {\n loadMore();\n }\n return true;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setHighlightIndex(\n (highlightIndex - 1 + Math.max(len, 1)) % Math.max(len, 1),\n );\n return true;\n }\n if (e.key === \"Enter\") {\n e.preventDefault();\n const item = filteredOptions[highlightIndex];\n if (item) selectOption(item, textarea);\n return true;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n closeSuggestions();\n return true;\n }\n return false;\n },\n [\n activeTrigger,\n filteredOptions,\n highlightIndex,\n searchState,\n selectOption,\n closeSuggestions,\n loadMore,\n ],\n );\n\n return {\n visible,\n setVisible,\n mentions,\n activeTrigger,\n filteredOptions,\n highlightIndex,\n setHighlightIndex,\n searchLoading: searchState.loading,\n searchHasMore: searchState.hasMore,\n handleTextChange,\n handleKeyDown,\n selectOption,\n closeSuggestions,\n loadMore,\n rawToVisible,\n visibleToRaw,\n caretPosRef,\n getItemForMention,\n };\n}\n\nfunction getItemKey(trigger: MentionTrigger<any>, item: unknown): string {\n const serialized = trigger.serialize(item);\n const re = new RegExp(\n trigger.pattern.source,\n trigger.pattern.flags.replace(\"g\", \"\"),\n );\n const m = re.exec(serialized);\n if (m) {\n return trigger.parseMatch(m).key;\n }\n return serialized;\n}\n",
10
10
  "export function escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"
11
11
  ],
12
- "mappings": "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",
13
- "debugId": "436A2E507826B04564756E2164756E21",
12
+ "mappings": "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",
13
+ "debugId": "0811411863941EFA64756E2164756E21",
14
14
  "names": []
15
15
  }
@@ -1,4 +1,10 @@
1
1
  import type React from "react";
2
+ export interface MentionItemData {
3
+ key: string;
4
+ displayText: string;
5
+ trigger: string;
6
+ item: unknown;
7
+ }
2
8
  export interface MentionTrigger<T = unknown> {
3
9
  /** The character(s) that activate this trigger (e.g., "@", "#") */
4
10
  trigger: string;
@@ -22,10 +28,14 @@ export interface MentionTrigger<T = unknown> {
22
28
  }>;
23
29
  /** Custom option rendering */
24
30
  renderOption?: (item: T, highlighted: boolean) => React.ReactNode;
31
+ /** CSS class for dropdown options, or a function for conditional styling per item */
32
+ optionClassName?: string | ((item: T) => string);
25
33
  /** Custom mention highlight rendering */
26
- renderMention?: (displayText: string) => React.ReactNode;
27
- /** CSS class for highlighted mentions in the overlay */
28
- mentionClassName?: string;
34
+ renderMention?: (displayText: string, item?: unknown) => React.ReactNode;
35
+ /** CSS class for highlighted mentions in the overlay, or a function for conditional styling */
36
+ mentionClassName?: string | ((mention: MentionItemData) => string);
37
+ /** Action trigger: called instead of inserting a mention. Return string to insert as plain text, or null to cancel. */
38
+ onSelect?: (item: T) => Promise<string | null> | string | null;
29
39
  }
30
40
  export interface MentionInputProps {
31
41
  triggers: MentionTrigger<any>[];
@@ -48,6 +58,8 @@ export interface MentionInputProps {
48
58
  dropdownClassName?: string;
49
59
  /** Dropdown width in pixels */
50
60
  dropdownWidth?: number;
61
+ /** Text shown while loading async results (default: "Loading...") */
62
+ loadingText?: string;
51
63
  /** Full custom dropdown rendering */
52
64
  renderDropdown?: (props: DropdownRenderProps) => React.ReactNode;
53
65
  "aria-label"?: string;
@@ -29,5 +29,6 @@ export declare function useMentionEngine(options: MentionEngineOptions): {
29
29
  rawToVisible: (raw: string) => string;
30
30
  visibleToRaw: (vis: string, mentionsList: ActiveMention[]) => string;
31
31
  caretPosRef: import("react").RefObject<number | null>;
32
+ getItemForMention: (triggerChar: string, key: string) => unknown;
32
33
  };
33
34
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mentionize",
3
3
  "author": "canta2899",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "description": "A dependency-free React mention input with support for multiple triggers, async search, and full customization",
6
6
  "type": "module",
7
7
  "main": "./dist/cjs/index.js",