mentionize 0.0.1 → 0.0.3

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.
@@ -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 // If parseMatch returned an item, seed the cache (replaces null placeholders too)\n if (parsed.item !== undefined) {\n if (!cache.has(parsed.key) || cache.get(parsed.key) === null) {\n cache.set(parsed.key, parsed.item);\n }\n } else 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": "B71F10C79A7CF6EF64756E2164756E21",
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;
@@ -8,10 +14,14 @@ export interface MentionTrigger<T = unknown> {
8
14
  serialize: (item: T) => string;
9
15
  /** Regex to detect serialized mentions in raw text. Must use global flag. */
10
16
  pattern: RegExp;
11
- /** Parse a regex match back into display text and a unique key */
17
+ /** Parse a regex match back into display text and a unique key.
18
+ * Optionally return `item` to seed the engine cache — useful when
19
+ * mentions are injected externally (e.g. via a command picker) and
20
+ * the item wouldn't otherwise be in cache at parse time. */
12
21
  parseMatch: (match: RegExpExecArray) => {
13
22
  displayText: string;
14
23
  key: string;
24
+ item?: T;
15
25
  };
16
26
  /** Static options array */
17
27
  options?: T[];
@@ -22,10 +32,14 @@ export interface MentionTrigger<T = unknown> {
22
32
  }>;
23
33
  /** Custom option rendering */
24
34
  renderOption?: (item: T, highlighted: boolean) => React.ReactNode;
35
+ /** CSS class for dropdown options, or a function for conditional styling per item */
36
+ optionClassName?: string | ((item: T) => string);
25
37
  /** Custom mention highlight rendering */
26
- renderMention?: (displayText: string) => React.ReactNode;
27
- /** CSS class for highlighted mentions in the overlay */
28
- mentionClassName?: string;
38
+ renderMention?: (displayText: string, item?: unknown) => React.ReactNode;
39
+ /** CSS class for highlighted mentions in the overlay, or a function for conditional styling */
40
+ mentionClassName?: string | ((mention: MentionItemData) => string);
41
+ /** Action trigger: called instead of inserting a mention. Return string to insert as plain text, or null to cancel. */
42
+ onSelect?: (item: T) => Promise<string | null> | string | null;
29
43
  }
30
44
  export interface MentionInputProps {
31
45
  triggers: MentionTrigger<any>[];
@@ -48,6 +62,8 @@ export interface MentionInputProps {
48
62
  dropdownClassName?: string;
49
63
  /** Dropdown width in pixels */
50
64
  dropdownWidth?: number;
65
+ /** Text shown while loading async results (default: "Loading...") */
66
+ loadingText?: string;
51
67
  /** Full custom dropdown rendering */
52
68
  renderDropdown?: (props: DropdownRenderProps) => React.ReactNode;
53
69
  "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)
@@ -402,7 +421,11 @@ function useMentionEngine(options) {
402
421
  parts.push(result.slice(lastIndex, m.index));
403
422
  const parsed = t.parseMatch(m);
404
423
  const cache = getCache(t.trigger);
405
- if (!cache.has(parsed.key)) {
424
+ if (parsed.item !== undefined) {
425
+ if (!cache.has(parsed.key) || cache.get(parsed.key) === null) {
426
+ cache.set(parsed.key, parsed.item);
427
+ }
428
+ } else if (!cache.has(parsed.key)) {
406
429
  cache.set(parsed.key, null);
407
430
  }
408
431
  parts.push(t.trigger + parsed.displayText);
@@ -574,10 +597,41 @@ function useMentionEngine(options) {
574
597
  setActiveTrigger(null);
575
598
  }
576
599
  }, [detectActiveTrigger, emitSync]);
600
+ const getItemForMention = useCallback3((triggerChar, key) => {
601
+ const cache = getCache(triggerChar);
602
+ return cache.get(key) ?? null;
603
+ }, []);
577
604
  const selectOption = useCallback3((item, textarea) => {
578
605
  if (!activeTrigger)
579
606
  return;
580
607
  const t = activeTrigger.trigger;
608
+ if (t.onSelect) {
609
+ const before2 = visible.slice(0, activeTrigger.startPos);
610
+ const after2 = visible.slice(textarea.selectionStart);
611
+ const savedStartPos = activeTrigger.startPos;
612
+ setActiveTrigger(null);
613
+ const result = t.onSelect(item);
614
+ const applyResult = (value) => {
615
+ if (value !== null) {
616
+ const newVis2 = before2 + value + after2;
617
+ const pos2 = savedStartPos + value.length;
618
+ caretPosRef.current = pos2;
619
+ setVisible(newVis2);
620
+ emitSync(newVis2);
621
+ } else {
622
+ const newVis2 = before2 + after2;
623
+ caretPosRef.current = savedStartPos;
624
+ setVisible(newVis2);
625
+ emitSync(newVis2);
626
+ }
627
+ };
628
+ if (result instanceof Promise) {
629
+ result.then(applyResult);
630
+ } else {
631
+ applyResult(result);
632
+ }
633
+ return;
634
+ }
581
635
  const cache = getCache(t.trigger);
582
636
  const key = getItemKey(t, item);
583
637
  cache.set(key, item);
@@ -655,7 +709,8 @@ function useMentionEngine(options) {
655
709
  loadMore,
656
710
  rawToVisible,
657
711
  visibleToRaw,
658
- caretPosRef
712
+ caretPosRef,
713
+ getItemForMention
659
714
  };
660
715
  }
661
716
  function getItemKey(trigger, item) {
@@ -695,6 +750,7 @@ var MentionInput = forwardRef(({
695
750
  highlighterClassName,
696
751
  dropdownClassName,
697
752
  dropdownWidth = 250,
753
+ loadingText,
698
754
  renderDropdown,
699
755
  "aria-label": ariaLabel,
700
756
  "aria-describedby": ariaDescribedBy
@@ -767,6 +823,7 @@ var MentionInput = forwardRef(({
767
823
  mentions: engine.mentions,
768
824
  triggers,
769
825
  textareaRef,
826
+ getItemForMention: engine.getItemForMention,
770
827
  className: highlighterClassName,
771
828
  style: SHARED_STYLE
772
829
  }, undefined, false, undefined, this),
@@ -824,6 +881,7 @@ var MentionInput = forwardRef(({
824
881
  onSelect: handleSelect,
825
882
  onLoadMore: engine.searchHasMore ? engine.loadMore : undefined,
826
883
  loading: engine.searchLoading,
884
+ loadingText,
827
885
  position: dropdownPos,
828
886
  width: dropdownWidth,
829
887
  className: dropdownClassName
@@ -840,5 +898,5 @@ export {
840
898
  MentionDropdown
841
899
  };
842
900
 
843
- //# debugId=436A2E507826B04564756E2164756E21
901
+ //# debugId=494A70F95392B04064756E2164756E21
844
902
  //# sourceMappingURL=index.js.map