@ttt-productions/chat-core 0.4.22 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +6 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -5
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mentions/MentionAutocomplete.d.ts +22 -0
- package/dist/mentions/MentionAutocomplete.d.ts.map +1 -0
- package/dist/mentions/MentionAutocomplete.js +21 -0
- package/dist/mentions/MentionAutocomplete.js.map +1 -0
- package/dist/mentions/MessageText.d.ts +27 -0
- package/dist/mentions/MessageText.d.ts.map +1 -0
- package/dist/mentions/MessageText.js +20 -0
- package/dist/mentions/MessageText.js.map +1 -0
- package/dist/mentions/parser.d.ts +33 -0
- package/dist/mentions/parser.d.ts.map +1 -0
- package/dist/mentions/parser.js +61 -0
- package/dist/mentions/parser.js.map +1 -0
- package/dist/mentions/types.d.ts +91 -0
- package/dist/mentions/types.d.ts.map +1 -0
- package/dist/mentions/types.js +14 -0
- package/dist/mentions/types.js.map +1 -0
- package/dist/mentions/use-mention-autocomplete.d.ts +81 -0
- package/dist/mentions/use-mention-autocomplete.d.ts.map +1 -0
- package/dist/mentions/use-mention-autocomplete.js +323 -0
- package/dist/mentions/use-mention-autocomplete.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +3 -0
- package/dist/react/index.js.map +1 -1
- package/dist/schemas/index.d.ts +14 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +14 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/types.d.ts +72 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/ChatShell.d.ts.map +1 -1
- package/dist/ui/ChatShell.js +1 -1
- package/dist/ui/ChatShell.js.map +1 -1
- package/dist/ui/Composer.d.ts +1 -0
- package/dist/ui/Composer.d.ts.map +1 -1
- package/dist/ui/Composer.js +30 -14
- package/dist/ui/Composer.js.map +1 -1
- package/dist/ui/MessageItemDefault.d.ts.map +1 -1
- package/dist/ui/MessageItemDefault.js +3 -2
- package/dist/ui/MessageItemDefault.js.map +1 -1
- package/package.json +8 -4
- package/src/styles/chat.css +14 -0
package/dist/constants.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Maximum chat message text length (characters). Consumer apps may override
|
|
3
|
+
* by passing a custom value through `ChatCoreConfig`; this constant is the
|
|
4
|
+
* package default and is also what chat-core's own internal schemas use.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MAX_CHAT_MESSAGE_LENGTH = 4000;
|
|
4
7
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Chat-domain limits and operational constants.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Maximum chat message text length (characters). Consumer apps may override
|
|
4
|
+
* by passing a custom value through `ChatCoreConfig`; this constant is the
|
|
5
|
+
* package default and is also what chat-core's own internal schemas use.
|
|
6
|
+
*/
|
|
7
|
+
export const MAX_CHAT_MESSAGE_LENGTH = 4000;
|
|
7
8
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { MAX_CHAT_MESSAGE_LENGTH
|
|
1
|
+
export { MAX_CHAT_MESSAGE_LENGTH } from "./constants.js";
|
|
2
2
|
export { GROUP_GAP_SEC } from "./types.js";
|
|
3
3
|
export { isContinuation } from "./grouping.js";
|
|
4
|
-
export type { ChatAttachment, ChatId, ChatThreadV1, ChatMessageV1, ChatAccessMode, ChatCoreConfig, ChatAttachmentConfig, SendAttachmentInput, SendAttachmentFn, ModerationHandlers, MessageRenderer, MessageRendererRegistry, ChatNameResolver, ChatPrewarmSenders, } from "./types.js";
|
|
4
|
+
export type { ChatAttachment, ChatId, ChatThreadV1, ChatMessageV1, ChatAccessMode, ChatCoreConfig, ChatAttachmentConfig, SendAttachmentInput, SendAttachmentFn, ModerationHandlers, MessageRenderer, MessageRendererRegistry, ChatNameResolver, ChatPrewarmSenders, ChatMentionConfig, } from "./types.js";
|
|
5
|
+
export type { MentionRef, ParsedSegment, MentionProvider, RecentMentionsAdapter, MentionAnchor, } from "./mentions/types.js";
|
|
6
|
+
export { parseMentionTokens, formatMentionToken } from "./mentions/parser.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EACR,cAAc,EACd,MAAM,EACN,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GACpB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,aAAa,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Server-safe barrel. React UI, hooks, and the ChatNameResolver context
|
|
2
2
|
// live on the "/react" subpath. Cloud Functions and other server code
|
|
3
3
|
// import from this barrel only.
|
|
4
|
-
export { MAX_CHAT_MESSAGE_LENGTH
|
|
4
|
+
export { MAX_CHAT_MESSAGE_LENGTH } from "./constants.js";
|
|
5
5
|
export { GROUP_GAP_SEC } from "./types.js";
|
|
6
6
|
export { isContinuation } from "./grouping.js";
|
|
7
|
+
export { parseMentionTokens, formatMentionToken } from "./mentions/parser.js";
|
|
7
8
|
// CSS: import "@ttt-productions/chat-core/styles" in your app layout.
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,sEAAsE;AACtE,gCAAgC;AAEhC,OAAO,EAAE,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,sEAAsE;AACtE,gCAAgC;AAEhC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AA0B/C,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,sEAAsE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visual autocomplete dropdown for the mention system.
|
|
3
|
+
*
|
|
4
|
+
* Pure presentation — driven entirely by `state` from `useMentionAutocomplete`.
|
|
5
|
+
* The consumer is expected to absolutely-position this near the textarea (or
|
|
6
|
+
* use its caret position via a wrapping container). chat-core does not
|
|
7
|
+
* compute textarea-caret coordinates; that's the consumer's job.
|
|
8
|
+
*
|
|
9
|
+
* Selecting a result fires `onSelect(ref)`. Hovering / arrow-keying updates
|
|
10
|
+
* the highlight via `onHighlight(index)`.
|
|
11
|
+
*/
|
|
12
|
+
import type { AutocompleteState } from './use-mention-autocomplete.js';
|
|
13
|
+
import type { MentionRef } from './types.js';
|
|
14
|
+
export interface MentionAutocompleteProps<TKind extends string = string> {
|
|
15
|
+
state: AutocompleteState<TKind>;
|
|
16
|
+
onSelect: (ref: MentionRef<TKind>) => void;
|
|
17
|
+
onHighlight?: (flatIndex: number) => void;
|
|
18
|
+
/** Class name applied to the outer container. */
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function MentionAutocomplete<TKind extends string = string>(props: MentionAutocompleteProps<TKind>): import("react/jsx-runtime").JSX.Element | null;
|
|
22
|
+
//# sourceMappingURL=MentionAutocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionAutocomplete.d.ts","sourceRoot":"","sources":["../../src/mentions/MentionAutocomplete.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,wBAAwB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACrE,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAC3C,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAC/D,KAAK,EAAE,wBAAwB,CAAC,KAAK,CAAC,kDAoEvC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '@ttt-productions/ui-core';
|
|
4
|
+
export function MentionAutocomplete(props) {
|
|
5
|
+
const { state, onSelect, onHighlight, className } = props;
|
|
6
|
+
if (!state.open)
|
|
7
|
+
return null;
|
|
8
|
+
const anyResults = state.flatResults.length > 0;
|
|
9
|
+
const anyLoading = state.groups.some((g) => g.loading);
|
|
10
|
+
let flatIndex = 0;
|
|
11
|
+
return (_jsxs("div", { role: "listbox", "aria-label": "Mentions", className: cn('chat-mention-autocomplete', 'rounded-md border bg-popover text-popover-foreground shadow-md', 'max-h-72 overflow-y-auto min-w-[16rem]', className), children: [!anyResults && anyLoading && (_jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground", children: "Searching\u2026" })), !anyResults && !anyLoading && (_jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground", children: state.showingRecent ? 'No recent mentions' : 'No matches' })), state.groups.map((group) => (_jsxs("div", { className: "chat-mention-group", children: [_jsx("div", { className: "px-3 pt-2 pb-1 text-xs font-semibold text-muted-foreground", children: state.showingRecent ? `Recent ${group.label}` : group.label }), group.loading && group.results.length === 0 && (_jsx("div", { className: "px-3 pb-2 text-xs text-muted-foreground", children: "Loading\u2026" })), _jsx("ul", { children: group.results.map((ref) => {
|
|
12
|
+
const myIndex = flatIndex;
|
|
13
|
+
flatIndex += 1;
|
|
14
|
+
const highlighted = myIndex === state.highlightedIndex;
|
|
15
|
+
return (_jsx("li", { children: _jsx("button", { type: "button", role: "option", "aria-selected": highlighted, className: cn('w-full text-left px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground', highlighted && 'bg-accent text-accent-foreground'), onMouseEnter: () => onHighlight?.(myIndex), onClick: (e) => {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
onSelect(ref);
|
|
18
|
+
}, children: group.renderResult ? group.renderResult(ref) : _jsxs("span", { children: ["@", ref.displayText] }) }) }, `${ref.kind}:${ref.id}`));
|
|
19
|
+
}) })] }, group.kind)))] }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=MentionAutocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionAutocomplete.js","sourceRoot":"","sources":["../../src/mentions/MentionAutocomplete.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAgBb,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAU9C,MAAM,UAAU,mBAAmB,CACjC,KAAsC;IAEtC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC1D,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAE7B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEvD,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO,CACL,eACE,IAAI,EAAC,SAAS,gBACH,UAAU,EACrB,SAAS,EAAE,EAAE,CACX,2BAA2B,EAC3B,gEAAgE,EAChE,wCAAwC,EACxC,SAAS,CACV,aAEA,CAAC,UAAU,IAAI,UAAU,IAAI,CAC5B,cAAK,SAAS,EAAC,yCAAyC,gCAAiB,CAC1E,EACA,CAAC,UAAU,IAAI,CAAC,UAAU,IAAI,CAC7B,cAAK,SAAS,EAAC,yCAAyC,YACrD,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,YAAY,GACtD,CACP,EACA,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC3B,eAAsB,SAAS,EAAC,oBAAoB,aAClD,cAAK,SAAS,EAAC,4DAA4D,YACxE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GACxD,EACL,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAC9C,cAAK,SAAS,EAAC,yCAAyC,8BAAe,CACxE,EACD,uBACG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;4BACzB,MAAM,OAAO,GAAG,SAAS,CAAC;4BAC1B,SAAS,IAAI,CAAC,CAAC;4BACf,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,CAAC,gBAAgB,CAAC;4BACvD,OAAO,CACL,uBACE,iBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,mBACE,WAAW,EAC1B,SAAS,EAAE,EAAE,CACX,iFAAiF,EACjF,WAAW,IAAI,kCAAkC,CAClD,EACD,YAAY,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,EAC1C,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;wCACb,CAAC,CAAC,cAAc,EAAE,CAAC;wCACnB,QAAQ,CAAC,GAAG,CAAC,CAAC;oCAChB,CAAC,YAEA,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,gCAAQ,GAAG,CAAC,WAAW,IAAQ,GACxE,IAhBF,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,EAAE,CAiB3B,CACN,CAAC;wBACJ,CAAC,CAAC,GACC,KAjCG,KAAK,CAAC,IAAI,CAkCd,CACP,CAAC,IACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders message text with inline mention chips.
|
|
3
|
+
*
|
|
4
|
+
* Walks the parser output and renders each segment: text segments as
|
|
5
|
+
* `<span>`, mention segments via the consumer-supplied `renderMention`
|
|
6
|
+
* callback (or a default chip when omitted).
|
|
7
|
+
*
|
|
8
|
+
* Pure, no context. Safe to use inside MessageItem renderers, ReplyQuote
|
|
9
|
+
* previews, or any other text surface that should honor mention tokens.
|
|
10
|
+
*/
|
|
11
|
+
import type { ReactNode } from 'react';
|
|
12
|
+
import type { MentionRef } from './types.js';
|
|
13
|
+
export interface MessageTextProps<TKind extends string = string> {
|
|
14
|
+
/** Raw message text containing optional `@[kind:id|displayText]` tokens. */
|
|
15
|
+
text: string;
|
|
16
|
+
/**
|
|
17
|
+
* Custom mention renderer. When omitted, mentions render as a
|
|
18
|
+
* `<span class="chat-mention-chip">@{displayText}</span>` chip — consumers
|
|
19
|
+
* style via CSS. To make mentions clickable / linked / role-aware, supply
|
|
20
|
+
* a renderMention.
|
|
21
|
+
*/
|
|
22
|
+
renderMention?: (ref: MentionRef<TKind>) => ReactNode;
|
|
23
|
+
/** Optional className applied to the wrapping `<span>`. */
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function MessageText<TKind extends string = string>(props: MessageTextProps<TKind>): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
//# sourceMappingURL=MessageText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageText.d.ts","sourceRoot":"","sources":["../../src/mentions/MessageText.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,gBAAgB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IAC7D,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;IACtD,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,2CAiBxF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { parseMentionTokens } from './parser.js';
|
|
4
|
+
function DefaultMentionChip({ ref }) {
|
|
5
|
+
return (_jsxs("span", { className: "chat-mention-chip", "data-mention-kind": ref.kind, "data-mention-id": ref.id, children: ["@", ref.displayText] }));
|
|
6
|
+
}
|
|
7
|
+
export function MessageText(props) {
|
|
8
|
+
const { text, renderMention, className } = props;
|
|
9
|
+
const segments = parseMentionTokens(text);
|
|
10
|
+
return (_jsx("span", { className: className, children: segments.map((seg, i) => {
|
|
11
|
+
if (seg.type === 'text') {
|
|
12
|
+
return _jsx("span", { children: seg.text }, i);
|
|
13
|
+
}
|
|
14
|
+
if (renderMention) {
|
|
15
|
+
return _jsx("span", { children: renderMention(seg.ref) }, i);
|
|
16
|
+
}
|
|
17
|
+
return _jsx(DefaultMentionChip, { ref: seg.ref }, i);
|
|
18
|
+
}) }));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=MessageText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageText.js","sourceRoot":"","sources":["../../src/mentions/MessageText.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAeb,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAgBjD,SAAS,kBAAkB,CAAuB,EAAE,GAAG,EAA8B;IACnF,OAAO,CACL,gBAAM,SAAS,EAAC,mBAAmB,uBAAoB,GAAG,CAAC,IAAI,qBAAmB,GAAG,CAAC,EAAE,kBACpF,GAAG,CAAC,WAAW,IACZ,CACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAgC,KAA8B;IACvF,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACjD,MAAM,QAAQ,GAAG,kBAAkB,CAAQ,IAAI,CAAC,CAAC;IAEjD,OAAO,CACL,eAAM,SAAS,EAAE,SAAS,YACvB,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACvB,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxB,OAAO,yBAAe,GAAG,CAAC,IAAI,IAAZ,CAAC,CAAmB,CAAC;YACzC,CAAC;YACD,IAAI,aAAa,EAAE,CAAC;gBAClB,OAAO,yBAAe,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAA1B,CAAC,CAAiC,CAAC;YACvD,CAAC;YACD,OAAO,KAAC,kBAAkB,IAAS,GAAG,EAAE,GAAG,CAAC,GAAG,IAAf,CAAC,CAAkB,CAAC;QACtD,CAAC,CAAC,GACG,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mention token parser.
|
|
3
|
+
*
|
|
4
|
+
* Token grammar:
|
|
5
|
+
* @[kind:id] — minimal form; displayText defaults to id
|
|
6
|
+
* @[kind:id|displayText] — full form
|
|
7
|
+
*
|
|
8
|
+
* kind : [A-Za-z0-9-]+
|
|
9
|
+
* id : [^\]|]+
|
|
10
|
+
* displayText : [^\]]* (may be empty; defaults to id when omitted)
|
|
11
|
+
*
|
|
12
|
+
* Anything not matching the grammar is preserved verbatim as text segments.
|
|
13
|
+
* Malformed tokens (unterminated, illegal characters) are NOT parsed — they
|
|
14
|
+
* pass through as plain text so the user always sees what they typed.
|
|
15
|
+
*/
|
|
16
|
+
import type { MentionRef, ParsedSegment } from './types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Parse a string of message text into an ordered array of text and mention
|
|
19
|
+
* segments. Always returns at least one segment for non-empty input. For an
|
|
20
|
+
* empty string, returns an empty array.
|
|
21
|
+
*
|
|
22
|
+
* The parser is intentionally permissive in `TKind` — it returns mentions
|
|
23
|
+
* with `kind` typed as `TKind`, but does NOT validate that the parsed kind
|
|
24
|
+
* is a member of the consumer's union. Validation, if needed, is the
|
|
25
|
+
* consumer's job; the wire token is the source of truth.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseMentionTokens<TKind extends string = string>(text: string): Array<ParsedSegment<TKind>>;
|
|
28
|
+
/**
|
|
29
|
+
* Build a wire token from a MentionRef. Inverse of the parser's per-token
|
|
30
|
+
* branch — same grammar.
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatMentionToken<TKind extends string>(ref: MentionRef<TKind>): string;
|
|
33
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/mentions/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI5D;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAC9D,IAAI,EAAE,MAAM,GACX,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAgC7B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,MAAM,CAEvF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mention token parser.
|
|
3
|
+
*
|
|
4
|
+
* Token grammar:
|
|
5
|
+
* @[kind:id] — minimal form; displayText defaults to id
|
|
6
|
+
* @[kind:id|displayText] — full form
|
|
7
|
+
*
|
|
8
|
+
* kind : [A-Za-z0-9-]+
|
|
9
|
+
* id : [^\]|]+
|
|
10
|
+
* displayText : [^\]]* (may be empty; defaults to id when omitted)
|
|
11
|
+
*
|
|
12
|
+
* Anything not matching the grammar is preserved verbatim as text segments.
|
|
13
|
+
* Malformed tokens (unterminated, illegal characters) are NOT parsed — they
|
|
14
|
+
* pass through as plain text so the user always sees what they typed.
|
|
15
|
+
*/
|
|
16
|
+
const TOKEN_RE = /@\[([A-Za-z0-9-]+):([^\]|]+)(?:\|([^\]]*))?\]/g;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a string of message text into an ordered array of text and mention
|
|
19
|
+
* segments. Always returns at least one segment for non-empty input. For an
|
|
20
|
+
* empty string, returns an empty array.
|
|
21
|
+
*
|
|
22
|
+
* The parser is intentionally permissive in `TKind` — it returns mentions
|
|
23
|
+
* with `kind` typed as `TKind`, but does NOT validate that the parsed kind
|
|
24
|
+
* is a member of the consumer's union. Validation, if needed, is the
|
|
25
|
+
* consumer's job; the wire token is the source of truth.
|
|
26
|
+
*/
|
|
27
|
+
export function parseMentionTokens(text) {
|
|
28
|
+
if (text.length === 0)
|
|
29
|
+
return [];
|
|
30
|
+
const segments = [];
|
|
31
|
+
let lastIndex = 0;
|
|
32
|
+
TOKEN_RE.lastIndex = 0;
|
|
33
|
+
let match;
|
|
34
|
+
while ((match = TOKEN_RE.exec(text)) !== null) {
|
|
35
|
+
const [whole, kindRaw, idRaw, displayRaw] = match;
|
|
36
|
+
const start = match.index;
|
|
37
|
+
const end = start + whole.length;
|
|
38
|
+
if (start > lastIndex) {
|
|
39
|
+
segments.push({ type: 'text', text: text.slice(lastIndex, start) });
|
|
40
|
+
}
|
|
41
|
+
const ref = {
|
|
42
|
+
kind: kindRaw,
|
|
43
|
+
id: idRaw,
|
|
44
|
+
displayText: displayRaw && displayRaw.length > 0 ? displayRaw : idRaw,
|
|
45
|
+
};
|
|
46
|
+
segments.push({ type: 'mention', ref });
|
|
47
|
+
lastIndex = end;
|
|
48
|
+
}
|
|
49
|
+
if (lastIndex < text.length) {
|
|
50
|
+
segments.push({ type: 'text', text: text.slice(lastIndex) });
|
|
51
|
+
}
|
|
52
|
+
return segments;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a wire token from a MentionRef. Inverse of the parser's per-token
|
|
56
|
+
* branch — same grammar.
|
|
57
|
+
*/
|
|
58
|
+
export function formatMentionToken(ref) {
|
|
59
|
+
return `@[${ref.kind}:${ref.id}|${ref.displayText}]`;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/mentions/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,QAAQ,GAAG,gDAAgD,CAAC;AAElE;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY;IAEZ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,QAAQ,GAAgC,EAAE,CAAC;IACjD,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;IACvB,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;QAEjC,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,GAAG,GAAsB;YAC7B,IAAI,EAAE,OAAgB;YACtB,EAAE,EAAE,KAAK;YACT,WAAW,EAAE,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK;SACtE,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAExC,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC;IAED,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAuB,GAAsB;IAC7E,OAAO,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,WAAW,GAAG,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic mention system types.
|
|
3
|
+
*
|
|
4
|
+
* chat-core owns the mention infrastructure (parsing, autocomplete UI, keyboard
|
|
5
|
+
* behavior, composer insertion, message text rendering) but knows nothing about
|
|
6
|
+
* what a "user" or "project" is. The consumer parameterizes `TKind` to its own
|
|
7
|
+
* union and supplies one `MentionProvider` per kind.
|
|
8
|
+
*
|
|
9
|
+
* Wire format — mentions are encoded inline in the message's `text` field as
|
|
10
|
+
* `@[kind:id|displayText]` tokens. The renderer parses them out at display
|
|
11
|
+
* time. No schema change to ChatMessage.
|
|
12
|
+
*/
|
|
13
|
+
import type { ReactNode } from 'react';
|
|
14
|
+
/**
|
|
15
|
+
* Resolved mention — the value that ends up in the wire token after the user
|
|
16
|
+
* selects an autocomplete result.
|
|
17
|
+
*
|
|
18
|
+
* `kind` is the discriminator supplied by the consumer (e.g. `'member'`, `'tag'`); `id` is the
|
|
19
|
+
* consumer-chosen stable identifier; `displayText` is the user-facing label
|
|
20
|
+
* (typically a display name or title).
|
|
21
|
+
*/
|
|
22
|
+
export type MentionRef<TKind extends string = string> = {
|
|
23
|
+
kind: TKind;
|
|
24
|
+
id: string;
|
|
25
|
+
displayText: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Single segment in parsed message text. Either a literal text run or a
|
|
29
|
+
* resolved mention. The renderer walks an ordered array of these.
|
|
30
|
+
*/
|
|
31
|
+
export type ParsedSegment<TKind extends string = string> = {
|
|
32
|
+
type: 'text';
|
|
33
|
+
text: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'mention';
|
|
36
|
+
ref: MentionRef<TKind>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Provider supplying autocomplete results for one mention kind.
|
|
40
|
+
*
|
|
41
|
+
* - `kind` — the discriminator. Must match `MentionRef.kind` for results
|
|
42
|
+
* returned by `search`.
|
|
43
|
+
* - `label` — human-readable label for the section / tab.
|
|
44
|
+
* - `search` — async query. Receives the current query string (after the
|
|
45
|
+
* trigger character), the consumer-supplied `context`, and an optional
|
|
46
|
+
* `signal` for cancellation. Returns up to whatever limit the provider
|
|
47
|
+
* chooses; chat-core renders all returned results.
|
|
48
|
+
* - `renderResult` — optional custom row UI. When omitted, the autocomplete
|
|
49
|
+
* renders the `displayText` plain.
|
|
50
|
+
*
|
|
51
|
+
* `TContext` is consumer-owned — pass anything you need inside `search`
|
|
52
|
+
* (Firestore db, current user id, surface-specific filters). chat-core never
|
|
53
|
+
* inspects it.
|
|
54
|
+
*/
|
|
55
|
+
export type MentionProvider<TKind extends string = string, TContext = unknown> = {
|
|
56
|
+
kind: TKind;
|
|
57
|
+
label: string;
|
|
58
|
+
search: (args: {
|
|
59
|
+
query: string;
|
|
60
|
+
context: TContext;
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
}) => Promise<MentionRef<TKind>[]>;
|
|
63
|
+
renderResult?: (ref: MentionRef<TKind>) => ReactNode;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Optional recent-mentions adapter. When provided, the autocomplete UI shows
|
|
67
|
+
* recent picks when the user opens the dropdown without typing a query
|
|
68
|
+
* (or after typing fewer than the configured minimum characters).
|
|
69
|
+
*
|
|
70
|
+
* `getRecent` MAY be async — the autocomplete renders a spinner while it
|
|
71
|
+
* resolves. `recordUse` is fired after a successful selection so consumers
|
|
72
|
+
* can persist usage.
|
|
73
|
+
*/
|
|
74
|
+
export type RecentMentionsAdapter<TKind extends string = string> = {
|
|
75
|
+
getRecent: () => MentionRef<TKind>[] | Promise<MentionRef<TKind>[]>;
|
|
76
|
+
recordUse?: (ref: MentionRef<TKind>) => void | Promise<void>;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Anchor describing the position of an inserted mention inside the composer's
|
|
80
|
+
* text buffer. Tracked in component state so positionally-collocated mentions
|
|
81
|
+
* with the same display string disambiguate on send.
|
|
82
|
+
*
|
|
83
|
+
* - `start` / `end` — character offsets into the current textarea value.
|
|
84
|
+
* - `ref` — the resolved MentionRef.
|
|
85
|
+
*/
|
|
86
|
+
export type MentionAnchor<TKind extends string = string> = {
|
|
87
|
+
start: number;
|
|
88
|
+
end: number;
|
|
89
|
+
ref: MentionRef<TKind>;
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mentions/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI;IACtD,IAAI,EAAE,KAAK,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IACnD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,CAAA;CAAE,CAAC;AAEhD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,eAAe,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,QAAQ,GAAG,OAAO,IAAI;IAC/E,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,IAAI,EAAE;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,QAAQ,CAAC;QAClB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;CACtD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI;IACjE,SAAS,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;CACxB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic mention system types.
|
|
3
|
+
*
|
|
4
|
+
* chat-core owns the mention infrastructure (parsing, autocomplete UI, keyboard
|
|
5
|
+
* behavior, composer insertion, message text rendering) but knows nothing about
|
|
6
|
+
* what a "user" or "project" is. The consumer parameterizes `TKind` to its own
|
|
7
|
+
* union and supplies one `MentionProvider` per kind.
|
|
8
|
+
*
|
|
9
|
+
* Wire format — mentions are encoded inline in the message's `text` field as
|
|
10
|
+
* `@[kind:id|displayText]` tokens. The renderer parses them out at display
|
|
11
|
+
* time. No schema change to ChatMessage.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mentions/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composer-side mention autocomplete state hook.
|
|
3
|
+
*
|
|
4
|
+
* Detects when the user types the trigger character (default `@`) inside the
|
|
5
|
+
* provided textarea, captures the live query (the text between the trigger
|
|
6
|
+
* and the cursor), debounces searches across all configured providers, and
|
|
7
|
+
* tracks the anchor positions of inserted mentions so the composer can
|
|
8
|
+
* convert display text back to wire tokens on send.
|
|
9
|
+
*
|
|
10
|
+
* Returns an `AutocompleteState` value tailored for the `<MentionAutocomplete>`
|
|
11
|
+
* UI component, plus an `insertMention` action and a `getValueWithTokens`
|
|
12
|
+
* accessor the composer calls on send.
|
|
13
|
+
*
|
|
14
|
+
* Generic over `TKind` and `TContext`; chat-core inspects neither.
|
|
15
|
+
*/
|
|
16
|
+
import { type RefObject } from 'react';
|
|
17
|
+
import type { MentionAnchor, MentionProvider, MentionRef, RecentMentionsAdapter } from './types.js';
|
|
18
|
+
export type AutocompleteResultGroup<TKind extends string = string> = {
|
|
19
|
+
kind: TKind;
|
|
20
|
+
label: string;
|
|
21
|
+
results: MentionRef<TKind>[];
|
|
22
|
+
/** True if `search` is in flight for this provider. */
|
|
23
|
+
loading: boolean;
|
|
24
|
+
/** Provider-supplied custom renderer for individual results, if any. */
|
|
25
|
+
renderResult?: (ref: MentionRef<TKind>) => import('react').ReactNode;
|
|
26
|
+
};
|
|
27
|
+
export type AutocompleteState<TKind extends string = string> = {
|
|
28
|
+
/** True iff the dropdown should be visible. */
|
|
29
|
+
open: boolean;
|
|
30
|
+
/** Current query text (everything after the trigger up to the cursor). */
|
|
31
|
+
query: string;
|
|
32
|
+
/** Results grouped by provider, in the order the consumer passed providers. */
|
|
33
|
+
groups: AutocompleteResultGroup<TKind>[];
|
|
34
|
+
/** When true, groups are recent picks (`getRecent`) rather than search results. */
|
|
35
|
+
showingRecent: boolean;
|
|
36
|
+
/** Index of the currently highlighted result, flattened across all groups. */
|
|
37
|
+
highlightedIndex: number;
|
|
38
|
+
/** Flat array of all results in display order. Used internally for keyboard nav. */
|
|
39
|
+
flatResults: MentionRef<TKind>[];
|
|
40
|
+
};
|
|
41
|
+
export interface UseMentionAutocompleteArgs<TKind extends string, TContext> {
|
|
42
|
+
textareaRef: RefObject<HTMLTextAreaElement>;
|
|
43
|
+
/** Current textarea value (controlled). */
|
|
44
|
+
value: string;
|
|
45
|
+
/** Setter for the textarea value. */
|
|
46
|
+
onChange: (next: string) => void;
|
|
47
|
+
/** Providers in display order. Empty list disables the system entirely. */
|
|
48
|
+
providers: MentionProvider<TKind, TContext>[];
|
|
49
|
+
/** Consumer-controlled context passed to each provider's `search`. */
|
|
50
|
+
context: TContext;
|
|
51
|
+
/** Optional recent-mentions adapter. */
|
|
52
|
+
recent?: RecentMentionsAdapter<TKind>;
|
|
53
|
+
/** Trigger character. Defaults to `'@'`. Must be exactly one character. */
|
|
54
|
+
trigger?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Minimum query length to fire `search`. Below this, recent picks are shown
|
|
57
|
+
* (if `recent` is supplied) or the dropdown stays empty. Default: 0 (search
|
|
58
|
+
* fires immediately on trigger).
|
|
59
|
+
*/
|
|
60
|
+
minQueryLength?: number;
|
|
61
|
+
/** Debounce window in ms for search calls. Default: 200. */
|
|
62
|
+
searchDebounceMs?: number;
|
|
63
|
+
}
|
|
64
|
+
export interface UseMentionAutocompleteResult<TKind extends string = string> {
|
|
65
|
+
state: AutocompleteState<TKind>;
|
|
66
|
+
/** Handle keydown from the textarea — returns true if the event was handled. */
|
|
67
|
+
handleKeyDown: (event: import('react').KeyboardEvent<HTMLTextAreaElement>) => boolean;
|
|
68
|
+
/** Programmatically insert a mention at the trigger position (called by the autocomplete UI). */
|
|
69
|
+
insertMention: (ref: MentionRef<TKind>) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Returns the current textarea value with all tracked mention anchors
|
|
72
|
+
* substituted back to wire tokens. Call this from the composer's send path.
|
|
73
|
+
*/
|
|
74
|
+
getValueWithTokens: () => string;
|
|
75
|
+
/** Anchor list — exposed for tests and consumers that need the raw positions. */
|
|
76
|
+
anchors: MentionAnchor<TKind>[];
|
|
77
|
+
/** Close the dropdown imperatively (e.g. on send). */
|
|
78
|
+
close: () => void;
|
|
79
|
+
}
|
|
80
|
+
export declare function useMentionAutocomplete<TKind extends string, TContext>(args: UseMentionAutocompleteArgs<TKind, TContext>): UseMentionAutocompleteResult<TKind>;
|
|
81
|
+
//# sourceMappingURL=use-mention-autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mention-autocomplete.d.ts","sourceRoot":"","sources":["../../src/mentions/use-mention-autocomplete.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,UAAU,EACV,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,uBAAuB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI;IACnE,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAC7B,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,OAAO,OAAO,EAAE,SAAS,CAAC;CACtE,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI;IAC7D,+CAA+C;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,MAAM,EAAE,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;IACzC,mFAAmF;IACnF,aAAa,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,WAAW,0BAA0B,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ;IACxE,WAAW,EAAE,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAC5C,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,2EAA2E;IAC3E,SAAS,EAAE,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC9C,sEAAsE;IACtE,OAAO,EAAE,QAAQ,CAAC;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACtC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA4B,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACzE,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAChC,gFAAgF;IAChF,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,EAAE,aAAa,CAAC,mBAAmB,CAAC,KAAK,OAAO,CAAC;IACtF,iGAAiG;IACjG,aAAa,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAChD;;;OAGG;IACH,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,iFAAiF;IACjF,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;IAChC,sDAAsD;IACtD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,EACnE,IAAI,EAAE,0BAA0B,CAAC,KAAK,EAAE,QAAQ,CAAC,GAChD,4BAA4B,CAAC,KAAK,CAAC,CAgVrC"}
|