mentionize 0.0.4 → 0.0.6

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.
@@ -1,15 +1,9 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/MentionInput.tsx", "../../src/MentionDropdown.tsx", "../../src/MentionHighlighter.tsx", "../../src/useCaretPosition.ts", "../../src/useMentionEngine.ts", "../../src/utils.ts"],
3
+ "sources": [],
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 loadingContent,\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 loadingContent={loadingContent}\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 loadingContent?: React.ReactNode;\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 loadingContent,\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=\"\">{loadingContent ?? \"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
- "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 // 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
- "export function escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"
11
5
  ],
12
- "mappings": "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",
13
- "debugId": "A096570B392F408364756E2164756E21",
6
+ "mappings": "",
7
+ "debugId": "82EBD10CCBB1553564756E2164756E21",
14
8
  "names": []
15
9
  }
@@ -66,6 +66,12 @@ export interface MentionInputProps {
66
66
  loadingContent?: React.ReactNode;
67
67
  /** Full custom dropdown rendering */
68
68
  renderDropdown?: (props: DropdownRenderProps) => React.ReactNode;
69
+ /**
70
+ * How the dropdown is positioned. Use `"absolute"` when MentionInput is
71
+ * inside a CSS-transformed ancestor (e.g. a modal with translate(-50%,-50%)),
72
+ * because `position: fixed` is broken by CSS transforms. Defaults to `"fixed"`.
73
+ */
74
+ dropdownPositionStrategy?: "fixed" | "absolute";
69
75
  "aria-label"?: string;
70
76
  "aria-describedby"?: string;
71
77
  }
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "mentionize",
3
3
  "author": "canta2899",
4
- "version": "0.0.4",
4
+ "version": "0.0.6",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/canta2899/mentionize"
8
+ },
5
9
  "description": "A dependency-free React mention input with support for multiple triggers, async search, and full customization",
6
10
  "type": "module",
7
11
  "main": "./dist/cjs/index.js",