@runtypelabs/persona 4.7.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/animations/glyph-cycle.cjs +2 -2
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/glyph-cycle.js +2 -2
- package/dist/animations/{types-CSmiKRVa.d.cts → types-4ROVJ1gA.d.cts} +85 -3
- package/dist/animations/{types-CSmiKRVa.d.ts → types-4ROVJ1gA.d.ts} +85 -3
- package/dist/animations/wipe.cjs +2 -2
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-5EIIHQLQ.js +1 -0
- package/dist/chunk-IO5VVUKP.js +3 -0
- package/dist/chunk-IPVK3KOM.js +1 -0
- package/dist/chunk-UPO4GUFC.js +1 -0
- package/dist/codegen.cjs +13 -13
- package/dist/codegen.js +14 -14
- package/dist/context-mentions-7S5KVUTG.js +169 -0
- package/dist/context-mentions-inline-TTCN7ZM2.js +4 -0
- package/dist/context-mentions-inline.cjs +4 -0
- package/dist/context-mentions-inline.d.cts +203 -0
- package/dist/context-mentions-inline.d.ts +203 -0
- package/dist/context-mentions-inline.js +4 -0
- package/dist/context-mentions.cjs +295 -0
- package/dist/context-mentions.d.cts +7025 -0
- package/dist/context-mentions.d.ts +7025 -0
- package/dist/context-mentions.js +295 -0
- package/dist/index.cjs +99 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1507 -182
- package/dist/index.d.ts +1507 -182
- package/dist/index.global.js +88 -56
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +99 -68
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/launcher.global.js +3 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers.js +24 -24
- package/dist/plugin-kit.cjs +1 -1
- package/dist/plugin-kit.d.cts +17 -0
- package/dist/plugin-kit.d.ts +17 -0
- package/dist/plugin-kit.js +1 -1
- package/dist/runtype-tts-entry-UJAEF7NZ.js +1 -0
- package/dist/runtype-tts.js +1 -1
- package/dist/session-reconnect-JKIJBHS5.js +1 -0
- package/dist/smart-dom-reader.cjs +18 -17
- package/dist/smart-dom-reader.d.cts +1260 -16
- package/dist/smart-dom-reader.d.ts +1260 -16
- package/dist/smart-dom-reader.js +18 -17
- package/dist/testing.cjs +3 -3
- package/dist/testing.js +3 -3
- package/dist/theme-editor-preview.cjs +260 -58
- package/dist/theme-editor-preview.d.cts +1234 -15
- package/dist/theme-editor-preview.d.ts +1234 -15
- package/dist/theme-editor-preview.js +87 -58
- package/dist/theme-editor.cjs +10 -10
- package/dist/theme-editor.d.cts +1226 -15
- package/dist/theme-editor.d.ts +1226 -15
- package/dist/theme-editor.js +10 -10
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +76 -0
- package/dist/theme-reference.d.ts +76 -0
- package/dist/theme-reference.js +1 -1
- package/dist/voice-worklet-player.cjs +2 -2
- package/dist/voice-worklet-player.js +2 -2
- package/dist/webmcp-polyfill.js +2 -2
- package/dist/widget.css +1 -1
- package/package.json +16 -5
- package/src/artifacts-session.test.ts +178 -0
- package/src/client.test.ts +255 -1
- package/src/client.ts +157 -60
- package/src/components/artifact-card.test.ts +333 -0
- package/src/components/artifact-card.ts +75 -28
- package/src/components/artifact-inline.test.ts +1328 -0
- package/src/components/artifact-inline.ts +920 -0
- package/src/components/artifact-pane.test.ts +1042 -0
- package/src/components/artifact-pane.ts +440 -131
- package/src/components/artifact-preview.test.ts +1155 -0
- package/src/components/artifact-preview.ts +994 -0
- package/src/components/composer-parts.ts +3 -12
- package/src/components/context-mention-button.test.ts +70 -0
- package/src/components/context-mention-button.ts +82 -0
- package/src/components/context-mention-chip.ts +134 -0
- package/src/components/context-mention-menu.test.ts +508 -0
- package/src/components/context-mention-menu.ts +0 -0
- package/src/components/message-bubble.test.ts +175 -0
- package/src/components/message-bubble.ts +177 -19
- package/src/components/panel.ts +7 -10
- package/src/components/pill-composer-builder.test.ts +6 -2
- package/src/components/pill-composer-builder.ts +6 -6
- package/src/components/reasoning-bubble.ts +1 -13
- package/src/components/registry.ts +38 -3
- package/src/components/tool-bubble.ts +1 -13
- package/src/context-mentions-bundle.test.ts +163 -0
- package/src/context-mentions-entry.ts +185 -0
- package/src/context-mentions-inline-entry.test.ts +136 -0
- package/src/context-mentions-inline-entry.ts +226 -0
- package/src/context-mentions-inline-loader.test.ts +30 -0
- package/src/context-mentions-inline-loader.ts +36 -0
- package/src/context-mentions-inline.ts +15 -0
- package/src/context-mentions-loader.ts +32 -0
- package/src/context-mentions.ts +16 -0
- package/src/defaults.ts +1 -0
- package/src/generated/runtype-openapi-contract.ts +55 -3
- package/src/index-core.ts +46 -1
- package/src/index-global.ts +51 -0
- package/src/index.ts +8 -0
- package/src/markdown-parsers-loader.test.ts +158 -0
- package/src/markdown-parsers-loader.ts +83 -27
- package/src/plugin-kit.test.ts +40 -0
- package/src/plugin-kit.ts +39 -5
- package/src/runtime/host-layout.test.ts +163 -0
- package/src/runtime/host-layout.ts +110 -7
- package/src/runtime/init.ts +18 -61
- package/src/session.mentions.test.ts +175 -0
- package/src/session.test.ts +52 -4
- package/src/session.ts +197 -27
- package/src/smart-dom-reader.test.ts +129 -2
- package/src/smart-dom-reader.ts +127 -1
- package/src/styles/context-mention-menu-css.ts +176 -0
- package/src/styles/widget.css +1002 -152
- package/src/theme-editor/preview.ts +2 -0
- package/src/theme-editor/sections.test.ts +26 -1
- package/src/theme-editor/sections.ts +13 -5
- package/src/theme-reference.ts +2 -2
- package/src/tool-call-display-defaults.test.ts +1 -0
- package/src/types/theme.ts +79 -0
- package/src/types.ts +1041 -17
- package/src/ui.artifact-pane-gating.test.ts +636 -0
- package/src/ui.component-directive.test.ts +104 -0
- package/src/ui.composer-bar.test.ts +60 -2
- package/src/ui.detached-panel.test.ts +1049 -0
- package/src/ui.mention-submit.test.ts +235 -0
- package/src/ui.tool-display.test.ts +51 -0
- package/src/ui.ts +998 -159
- package/src/utils/artifact-custom-actions.ts +128 -0
- package/src/utils/artifact-display.test.ts +42 -0
- package/src/utils/artifact-display.ts +84 -0
- package/src/utils/artifact-file.test.ts +116 -0
- package/src/utils/artifact-file.ts +117 -0
- package/src/utils/artifact-gate.test.ts +112 -5
- package/src/utils/artifact-gate.ts +39 -14
- package/src/utils/artifact-loading-status.ts +55 -0
- package/src/utils/artifact-status-label.ts +190 -0
- package/src/utils/buttons.ts +7 -1
- package/src/utils/chunk-loader.test.ts +97 -0
- package/src/utils/chunk-loader.ts +88 -0
- package/src/utils/code-highlight.test.ts +186 -0
- package/src/utils/code-highlight.ts +400 -0
- package/src/utils/composer-contenteditable.test.ts +507 -0
- package/src/utils/composer-contenteditable.ts +626 -0
- package/src/utils/composer-document.test.ts +280 -0
- package/src/utils/composer-document.ts +293 -0
- package/src/utils/composer-history.test.ts +35 -7
- package/src/utils/composer-history.ts +30 -20
- package/src/utils/composer-input.ts +159 -0
- package/src/utils/context-mention-controller.test.ts +1215 -0
- package/src/utils/context-mention-controller.ts +1186 -0
- package/src/utils/context-mention-manager.test.ts +422 -0
- package/src/utils/context-mention-manager.ts +410 -0
- package/src/utils/context-mention-orchestrator.test.ts +538 -0
- package/src/utils/context-mention-orchestrator.ts +348 -0
- package/src/utils/icons.ts +2 -0
- package/src/utils/live-region.test.ts +108 -0
- package/src/utils/live-region.ts +94 -0
- package/src/utils/mention-channels.ts +63 -0
- package/src/utils/mention-llm-format.test.ts +91 -0
- package/src/utils/mention-llm-format.ts +79 -0
- package/src/utils/mention-matcher.test.ts +86 -0
- package/src/utils/mention-matcher.ts +221 -0
- package/src/utils/mention-token.ts +72 -0
- package/src/utils/mention-trigger.test.ts +155 -0
- package/src/utils/mention-trigger.ts +156 -0
- package/src/utils/roving-tablist.test.ts +152 -0
- package/src/utils/roving-tablist.ts +111 -0
- package/src/utils/spinner.ts +45 -0
- package/src/utils/theme.test.ts +76 -4
- package/src/utils/theme.ts +7 -0
- package/src/utils/tokens.ts +118 -11
- package/src/utils/tool-loading-animation.test.ts +32 -0
- package/src/utils/tool-loading-animation.ts +24 -0
- package/dist/chunk-DFBSCFYN.js +0 -1
- package/dist/runtype-tts-entry-HFUV2UF7.js +0 -1
- package/dist/session-reconnect-U77QFUR7.js +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure `@`-trigger detection for the composer mention menu.
|
|
3
|
+
*
|
|
4
|
+
* No DOM, no contenteditable — a small function over `(value, caret)` mirroring
|
|
5
|
+
* the Slack/Discord approach. Shared by the core orchestrator's lightweight
|
|
6
|
+
* "should I open?" pre-check and the lazy-loaded controller's full parse, so the
|
|
7
|
+
* trigger rule lives in exactly one place.
|
|
8
|
+
*/
|
|
9
|
+
type MentionTriggerMatch = {
|
|
10
|
+
/** Index of the trigger character in `value`. */
|
|
11
|
+
triggerIndex: number;
|
|
12
|
+
/** The text typed after the trigger, up to the caret (no leading trigger). */
|
|
13
|
+
query: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Capability object handed to a `command:"action"` handler. The widget exposes
|
|
18
|
+
* only composer-local operations; broader actions (clear the transcript, change
|
|
19
|
+
* theme) are wired by the host via closures over its own controller.
|
|
20
|
+
*/
|
|
21
|
+
type AgentWidgetContextMentionComposerCapability = {
|
|
22
|
+
/** Current composer text. */
|
|
23
|
+
getValue: () => string;
|
|
24
|
+
/** Replace composer text (fires `input`, moves caret to end, refocuses). */
|
|
25
|
+
setValue: (value: string) => void;
|
|
26
|
+
/** Submit the composer (same path as pressing send). */
|
|
27
|
+
submit: () => void;
|
|
28
|
+
};
|
|
29
|
+
/** Reference stored on a sent message for transcript fidelity + chip rendering. */
|
|
30
|
+
type AgentWidgetContextMentionRef = {
|
|
31
|
+
sourceId: string;
|
|
32
|
+
itemId: string;
|
|
33
|
+
label: string;
|
|
34
|
+
iconName?: string;
|
|
35
|
+
/** Accent color for the inline token (see `AgentWidgetContextMentionItem.color`). */
|
|
36
|
+
color?: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Pure, DOM-free document model for the inline-mention composer
|
|
41
|
+
* (`contextMentions.display: "inline"`).
|
|
42
|
+
*
|
|
43
|
+
* The canonical composer state is a flat, ordered list of blocks — text runs and
|
|
44
|
+
* atomic mention tokens — rather than a single string with range markers. Blocks
|
|
45
|
+
* make insert/remove, duplicate detection, and history round-trip explicit
|
|
46
|
+
* without parsing HTML. The DOM adapter (`composer-contenteditable.ts`) renders a
|
|
47
|
+
* document to a contenteditable surface and re-parses it back on input; this
|
|
48
|
+
* module owns everything that does not touch the DOM, so it is unit-testable in
|
|
49
|
+
* the Node env exactly like `mention-trigger.ts` and `composer-history.ts`.
|
|
50
|
+
*
|
|
51
|
+
* Two text projections exist, each for a distinct purpose:
|
|
52
|
+
* - `toDisplayText` — text + `@label` per mention (the human-readable, sent
|
|
53
|
+
* bubble / model-visible prose).
|
|
54
|
+
* - `toLogicalText` — text + `` (OBJECT REPLACEMENT CHAR) per mention. An
|
|
55
|
+
* INTERNAL index space only — never shown to the user, never
|
|
56
|
+
* sent to the model — that lets the existing
|
|
57
|
+
* `parseMentionTrigger` run over `(logicalText, caret)` with
|
|
58
|
+
* tokens standing in as single, query-terminating chars.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/** Stable id for one inline mention instance (DOM `data-mention-id`, history key). */
|
|
62
|
+
type ComposerMentionId = string;
|
|
63
|
+
/** One block in the composer document. Order is significant. */
|
|
64
|
+
type ComposerBlock = {
|
|
65
|
+
kind: "text";
|
|
66
|
+
value: string;
|
|
67
|
+
} | {
|
|
68
|
+
kind: "mention";
|
|
69
|
+
id: ComposerMentionId;
|
|
70
|
+
ref: AgentWidgetContextMentionRef;
|
|
71
|
+
};
|
|
72
|
+
/** Canonical inline-composer state. */
|
|
73
|
+
type ComposerDocument = {
|
|
74
|
+
blocks: ComposerBlock[];
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The composer input surface the mention controller drives, abstracted over the
|
|
79
|
+
* two editing modes:
|
|
80
|
+
*
|
|
81
|
+
* - **chip mode** (`display: "chip"`, default): a plain `<textarea>`. Logical
|
|
82
|
+
* text is the raw value and logical caret is `selectionStart`.
|
|
83
|
+
* - **inline mode** (`display: "inline"`, Phase 4): a contenteditable surface
|
|
84
|
+
* whose atomic mention tokens collapse to a single `` in the logical text
|
|
85
|
+
* (see `composer-document.ts`). Its adapter additionally implements the
|
|
86
|
+
* optional document/token methods below.
|
|
87
|
+
*
|
|
88
|
+
* The controller only ever touches the composer through this capability, so the
|
|
89
|
+
* same menu/keyboard/search engine serves both surfaces. `ComposerInputCapability`
|
|
90
|
+
* is a superset of the public `AgentWidgetContextMentionComposerCapability`
|
|
91
|
+
* (`getValue`/`setValue`/`submit`) — the single source of truth for composer
|
|
92
|
+
* access — so a client `command:"action"` handler receives the same object.
|
|
93
|
+
*
|
|
94
|
+
* IMPORTANT (bundle guard): this module imports the document model TYPE-ONLY, so
|
|
95
|
+
* the chip chunk (`context-mentions.js`) never pulls `composer-document.ts`
|
|
96
|
+
* runtime. The contenteditable adapter, which does need it, lives in the separate
|
|
97
|
+
* inline chunk. Keep it that way — see `context-mentions-bundle.test.ts`.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
interface ComposerInputCapability extends AgentWidgetContextMentionComposerCapability {
|
|
101
|
+
/** The editable element — ARIA target for the menu, and focus receiver. */
|
|
102
|
+
readonly element: HTMLElement;
|
|
103
|
+
/** Text used for trigger parsing. Chip: `=== getValue()`; inline: text + ``. */
|
|
104
|
+
getLogicalText: () => string;
|
|
105
|
+
/** Caret/selection in LOGICAL coordinates. */
|
|
106
|
+
getSelection: () => {
|
|
107
|
+
start: number;
|
|
108
|
+
end: number;
|
|
109
|
+
};
|
|
110
|
+
/** Move the caret/selection (logical coordinates). */
|
|
111
|
+
setSelection: (start: number, end?: number) => void;
|
|
112
|
+
/** Replace the plain text and place the caret. No input event, no focus. */
|
|
113
|
+
setValueWithCaret: (value: string, caret: number) => void;
|
|
114
|
+
/** Fire input listeners after a programmatic edit. */
|
|
115
|
+
dispatchInput: () => void;
|
|
116
|
+
focus: () => void;
|
|
117
|
+
/**
|
|
118
|
+
* INLINE ONLY (contenteditable). Bounding rect (VIEWPORT coordinates) of the
|
|
119
|
+
* LOGICAL character range `[start, end)`, or `null` when unmeasurable (invalid
|
|
120
|
+
* range or a zero-size/degenerate rect). Used to trigger-anchor the mention menu
|
|
121
|
+
* horizontally to the `@` glyph. Chip (textarea) adapters omit it — no cheap
|
|
122
|
+
* per-glyph rect without a mirror-div hack, so the menu stays composer-anchored
|
|
123
|
+
* (graceful degradation). Callers treat a missing method exactly like a `null`
|
|
124
|
+
* result.
|
|
125
|
+
*/
|
|
126
|
+
getLogicalRangeRect?: (start: number, end: number) => DOMRect | null;
|
|
127
|
+
/** Canonical document (inline mode). */
|
|
128
|
+
getDocument?: () => ComposerDocument;
|
|
129
|
+
/**
|
|
130
|
+
* INLINE ONLY. Replace the active trigger range (`match`, logical coordinates)
|
|
131
|
+
* with an atomic mention token and place the caret after it. Returns the new
|
|
132
|
+
* mention's id (resolve-tracking key), or `null` if the range no longer matches
|
|
133
|
+
* the document (stale menu). Chip adapters leave this undefined — the controller
|
|
134
|
+
* then falls back to `stripMentionQuery`.
|
|
135
|
+
*/
|
|
136
|
+
insertMentionAtTrigger?: (ref: AgentWidgetContextMentionRef, match: MentionTriggerMatch) => ComposerMentionId | null;
|
|
137
|
+
/**
|
|
138
|
+
* INLINE ONLY. Insert an atomic mention token at the current caret/selection
|
|
139
|
+
* (picker path — the affordance button opens with no trigger char to replace).
|
|
140
|
+
* Returns the new mention's id. Chip adapters leave this undefined.
|
|
141
|
+
*/
|
|
142
|
+
insertMentionAtSelection?: (ref: AgentWidgetContextMentionRef) => ComposerMentionId;
|
|
143
|
+
/**
|
|
144
|
+
* INLINE ONLY. Reflect a mention's resolve status on its live token element —
|
|
145
|
+
* used to surface resolve errors inline. Toggles the error styling for `"error"`
|
|
146
|
+
* and clears it otherwise. No-op for an unknown id. Chip adapters omit this.
|
|
147
|
+
*/
|
|
148
|
+
setMentionStatus?: (id: ComposerMentionId, status: "pending" | "resolved" | "error") => void;
|
|
149
|
+
/**
|
|
150
|
+
* INLINE ONLY. Replace the LOGICAL range `[start, end)` with plain `text`,
|
|
151
|
+
* preserving every mention token that lies outside the range, and place the
|
|
152
|
+
* caret after the inserted text. This is the token-safe edit the controller
|
|
153
|
+
* uses for query-strip / slash-completion / prompt-macro rewrites, since a plain
|
|
154
|
+
* `getValue()` string-slice would misalign against DISPLAY text (`@Label`
|
|
155
|
+
* expands a token to many chars) and re-rendering as one text block would
|
|
156
|
+
* destroy every token. Chip adapters omit it — there DISPLAY === LOGICAL, so the
|
|
157
|
+
* controller string-slices `getValue()` + `setValueWithCaret` instead.
|
|
158
|
+
*/
|
|
159
|
+
replaceLogicalRange?: (start: number, end: number, text: string) => void;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Inline-mention chunk entry — the HEAVY, DOM-bearing half of inline mode. Loaded
|
|
164
|
+
* on composer mount when `contextMentions.display === "inline"` and NEVER
|
|
165
|
+
* statically imported on the core path (the IIFE build marks
|
|
166
|
+
* `@runtypelabs/persona/context-mentions-inline` external; ESM/CJS mark the same
|
|
167
|
+
* subpath external via `build:client`). This is the only place the
|
|
168
|
+
* contenteditable engine + `composer-document` enter the widget at runtime.
|
|
169
|
+
*
|
|
170
|
+
* `mountInlineComposer` builds a contenteditable `ComposerInputCapability` that
|
|
171
|
+
* visually mirrors the live `<textarea>` and migrates its current value + caret.
|
|
172
|
+
* It does NOT touch the DOM tree or rebind listeners — the caller (`ui.ts`) swaps
|
|
173
|
+
* the element in place and re-points the composer's event handlers, because those
|
|
174
|
+
* live in the core and the chunk must stay free of that wiring.
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
interface InlineComposerMountContext {
|
|
178
|
+
/** The live composer textarea to migrate from (value + caret + look). */
|
|
179
|
+
textarea: HTMLTextAreaElement;
|
|
180
|
+
/**
|
|
181
|
+
* Build a token's full element. Supplied by the CORE orchestrator (which owns
|
|
182
|
+
* `createMentionTokenElement` + the shared icon renderer) so this lazy chunk
|
|
183
|
+
* never bundles the icon set — it already ships in core. The adapter marks the
|
|
184
|
+
* returned element `contenteditable="false"` and stamps `data-mention-id`.
|
|
185
|
+
*/
|
|
186
|
+
renderToken: (ref: AgentWidgetContextMentionRef) => HTMLElement;
|
|
187
|
+
/**
|
|
188
|
+
* Fired when a token is deleted from the composer (backspace/cut). The caller
|
|
189
|
+
* routes this to `engine.untrackMention(id)` so the manager aborts its resolve.
|
|
190
|
+
*/
|
|
191
|
+
onMentionRemoved?: (id: string) => void;
|
|
192
|
+
}
|
|
193
|
+
interface InlineComposerHandle {
|
|
194
|
+
/** The contenteditable input surface; hand this to `mountContextMentions`. */
|
|
195
|
+
input: ComposerInputCapability;
|
|
196
|
+
/** The contenteditable root element to swap in for the textarea. */
|
|
197
|
+
element: HTMLElement;
|
|
198
|
+
/** Detach the adapter's listeners on unmount. */
|
|
199
|
+
destroy: () => void;
|
|
200
|
+
}
|
|
201
|
+
declare function mountInlineComposer(ctx: InlineComposerMountContext): InlineComposerHandle;
|
|
202
|
+
|
|
203
|
+
export { type InlineComposerHandle, type InlineComposerMountContext, mountInlineComposer };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var le="@";function W(t){return t.kind==="text"?t.value.length:1}function O(t){let n=[],o=r=>{let l=n[n.length-1];l&&l.kind==="text"?l.value+=r:n.push({kind:"text",value:r})};(t.length===0||t[0].kind!=="text")&&n.push({kind:"text",value:""});for(let r of t){if(r.kind==="text"){o(r.value);continue}let l=n[n.length-1];(!l||l.kind!=="text")&&n.push({kind:"text",value:""}),n.push({kind:"mention",id:r.id,ref:r.ref}),n.push({kind:"text",value:""})}let e=n[n.length-1];return(!e||e.kind!=="text")&&n.push({kind:"text",value:""}),n}function Q(){return{blocks:[{kind:"text",value:""}]}}function H(t){return{blocks:[{kind:"text",value:t}]}}function P(t){return t.blocks.map(n=>n.kind==="text"?n.value:`${le}${n.ref.label}`).join("")}function R(t){return t.blocks.map(n=>n.kind==="text"?n.value:"\uFFFC").join("")}function L(t){return t.blocks.reduce((n,o)=>n+W(o),0)}function ce(t){let n=[];for(let o of t.blocks)o.kind==="mention"&&n.push({id:o.id,ref:o.ref});return n}function I(t,n){let o=[],e=[],r=0;for(let l of t){let u=W(l),p=r+u;if(p<=n)o.push(l);else if(r>=n)e.push(l);else if(l.kind==="text"){let b=n-r;b>0&&o.push({kind:"text",value:l.value.slice(0,b)}),b<u&&e.push({kind:"text",value:l.value.slice(b)})}else e.push(l);r=p}return{left:o,right:e}}function B(t,n,o,e){let r=I(t.blocks,n.start).left,l=I(t.blocks,n.end).right,u=l[0],p=u?.kind==="text"?u.value.charAt(0):"",b=p!==" "&&p!==" "&&p!==`
|
|
2
|
+
`,g=O([...r,{kind:"mention",id:e,ref:o},...b?[{kind:"text",value:" "}]:[],...l]),C=n.start+1+(p===`
|
|
3
|
+
`?0:1);return{doc:{blocks:g},caret:C}}function X(t,n){let o=0,e=0,r=!1;for(let u of t.blocks)u.kind==="mention"&&u.id===n&&(o=e,r=!0),e+=W(u);return r?{doc:{blocks:O(t.blocks.filter(u=>!(u.kind==="mention"&&u.id===n)))},caret:o}:{doc:t,caret:e}}function S(t,n,o,e){let r=L(t),l=Math.max(0,Math.min(n,o,r)),u=Math.min(r,Math.max(n,o,0)),p=I(t.blocks,l).left,b=I(t.blocks,u).right;return{doc:{blocks:O([...p,{kind:"text",value:e},...b])},caret:l+e.length}}function Y(t){let n=[];for(let o of t.blocks)o.kind==="text"?o.value.length>0&&n.push({kind:"text",text:o.value}):n.push({kind:"mention",ref:o.ref});return{content:P(t),contextMentions:ce(t).map(o=>o.ref),contentSegments:n}}function G(t){t&&(typeof t.requestSubmit=="function"?t.requestSubmit():t.dispatchEvent(new Event("submit",{bubbles:!0,cancelable:!0})))}var ue="persona-mention-token-error",k="data-mention-id",v="data-mention-prev-label",_="data-mention-prev-title",U=`
|
|
4
|
+
`;function y(t){return t.nodeType===1&&t.hasAttribute(k)}function Z(t){return t.nodeType===1&&t.tagName==="BR"}function D(t){return t.nodeType===3?t.data.length:y(t)||Z(t)?1:t.textContent?.length??0}function J(t,n,o){let e=0;for(let r of Array.from(t.childNodes)){if(r===n)return r.nodeType===3?e+o:e+(o>0?D(r):0);if(r.contains(n))return y(r)?e+1:e+ae(r,n,o);e+=D(r)}if(n===t){let r=0,l=Array.from(t.childNodes);for(let u=0;u<Math.min(o,l.length);u++)r+=D(l[u]);return r}return e}function ae(t,n,o){let e=0,r=l=>{if(l===n)return e+=l.nodeType===3?o:0,!0;if(l.nodeType===3)return e+=l.data.length,!1;for(let u of Array.from(l.childNodes))if(r(u))return!0;return!1};return r(t),e}function T(t,n){let o=0,e=Array.from(t.childNodes);for(let r=0;r<e.length;r++){let l=e[r],u=D(l);if(n<=o+u)return l.nodeType===3?{node:l,offset:n-o}:{node:t,offset:n<=o?r:r+1};o+=u}return{node:t,offset:e.length}}function de(t,n){let o=[];for(let e of Array.from(t.childNodes))if(y(e)){let r=e.getAttribute(k),l=n.get(r);l&&o.push({kind:"mention",id:r,ref:l})}else if(Z(e))o.push({kind:"text",value:U});else if(e.nodeType===3)o.push({kind:"text",value:e.data});else{let r=e.textContent??"";r&&o.push({kind:"text",value:r})}return o.length===0&&o.push({kind:"text",value:""}),{blocks:o}}function ee(t){let n=t.renderToken,o=new Map,e=t.element??document.createElement("div");e.setAttribute("contenteditable","true"),e.setAttribute("data-persona-composer-input",""),e.setAttribute("role","textbox"),e.setAttribute("aria-multiline","true"),e.classList.add("persona-composer-contenteditable"),t.placeholder!=null&&e.setAttribute("data-placeholder",t.placeholder);let r=!1,l=0,u=()=>de(e,o),p=c=>{e.replaceChildren();for(let s of c.blocks)if(s.kind==="text")s.value.length>0&&e.appendChild(document.createTextNode(s.value));else{o.set(s.id,s.ref);let i=n(s.ref);i.setAttribute("contenteditable","false"),i.setAttribute(k,s.id),e.appendChild(i)}},b=()=>{let s=e.getRootNode().activeElement;return s===e||s!=null&&e.contains(s)},g=(c,s)=>{if(l=c,!s?.focus&&!b())return;let i=typeof window<"u"?window.getSelection():null;if(!i)return;let d=T(e,c);try{let a=document.createRange();a.setStart(d.node,d.offset),a.collapse(!0),i.removeAllRanges(),i.addRange(a)}catch{}},C=()=>{e.dispatchEvent(new Event("input",{bubbles:!0}))},x=()=>{let c={start:l,end:l},s=typeof window<"u"?window.getSelection():null;if(!s||s.rangeCount===0)return c;let i=s.getRangeAt(0);if(!e.contains(i.startContainer))return c;let d=J(e,i.startContainer,i.startOffset),a=i.collapsed?d:J(e,i.endContainer,i.endOffset);return{start:Math.min(d,a),end:Math.max(d,a)}},A=()=>{let c=new Set;for(let s of Array.from(e.childNodes))y(s)&&c.add(s.getAttribute(k));for(let s of Array.from(o.keys()))c.has(s)||(o.delete(s),t.onMentionRemoved?.(s))},F=()=>{r||o.size!==0&&A()},V=()=>{r=!0},q=()=>{r=!1,A()},j=c=>{c.preventDefault();let s=c.clipboardData?.getData("text/plain")??"";if(typeof document.execCommand=="function")document.execCommand("insertText",!1,s);else{let{start:i,end:d}=x(),a=S(u(),i,d,s);p(a.doc),g(a.caret,{focus:!0}),A()}C()},$=c=>{if(r)return;let s=c.inputType;if(s==="insertParagraph"){c.preventDefault();let{start:M,end:E}=x(),K=S(u(),M,E,U);p(K.doc),g(K.caret,{focus:!0}),o.size>0&&A(),C();return}if(s!=="deleteContentBackward"&&s!=="deleteContentForward"||o.size===0)return;let{start:i,end:d}=x();if(i!==d)return;let a=u(),m=R(a),f=s==="deleteContentBackward"?i-1:i;if(f<0||f>=m.length||m[f]!=="\uFFFC")return;let h=0,N=null;for(let M of a.blocks){let E=M.kind==="text"?M.value.length:1;if(M.kind==="mention"&&f>=h&&f<h+E){N=M.id;break}h+=E}if(!N)return;c.preventDefault();let z=X(a,N);p(z.doc),g(z.caret,{focus:!0}),A(),C()},te=(c,s)=>{p(H(c)),g(s)},ne=(c,s)=>{if(!Number.isFinite(c)||!Number.isFinite(s)||s<=c)return null;try{let i=T(e,c),d=T(e,s),a=document.createRange();a.setStart(i.node,i.offset),a.setEnd(d.node,d.offset);let m=a.getBoundingClientRect();return m.width===0&&m.height===0?null:m}catch{return null}},oe=(c,s,i)=>{let d=S(u(),c,s,i);p(d.doc),g(d.caret,{focus:!0})},re=(c,s)=>{let i=u(),d=R(i),a=s.triggerIndex,m=s.triggerIndex+1+s.query.length;if(a<0||m>d.length||d.slice(a+1,m)!==s.query)return null;let f=t.generateId(),h=B(i,{start:a,end:m},c,f);return p(h.doc),g(h.caret,{focus:!0}),t.onMentionInserted?.(f,c),C(),f},ie=c=>{let s=u(),i=x(),a=typeof window<"u"&&!!window.getSelection()?.rangeCount&&e.contains(window.getSelection().getRangeAt(0).startContainer)?{start:i.start,end:i.end}:{start:L(s),end:L(s)},m=t.generateId(),f=B(s,a,c,m);return p(f.doc),g(f.caret,{focus:!0}),t.onMentionInserted?.(m,c),C(),m},se=(c,s)=>{for(let i of Array.from(e.childNodes))if(y(i)&&i.getAttribute(k)===c){let d=s==="error";if(i.classList.toggle(ue,d),d){i.hasAttribute(v)||(i.setAttribute(v,i.getAttribute("aria-label")??""),i.setAttribute(_,i.getAttribute("title")??""));let a=o.get(c)?.label??"";i.setAttribute("title",`${a}: failed to attach context`),i.setAttribute("aria-label",`${a}, failed to attach context`)}else if(i.hasAttribute(v)){let a=i.getAttribute(v),m=i.getAttribute(_);a?i.setAttribute("aria-label",a):i.removeAttribute("aria-label"),m?i.setAttribute("title",m):i.removeAttribute("title"),i.removeAttribute(v),i.removeAttribute(_)}return}};return e.addEventListener("input",F),e.addEventListener("compositionstart",V),e.addEventListener("compositionend",q),e.addEventListener("paste",j),e.addEventListener("beforeinput",$),p(Q()),{element:e,getValue:()=>P(u()),getLogicalText:()=>R(u()),getDocument:u,getSelection:x,setSelection:(c,s=c)=>{let i=typeof window<"u"?window.getSelection():null;if(i)try{let d=T(e,c),a=T(e,s),m=document.createRange();m.setStart(d.node,d.offset),m.setEnd(a.node,a.offset),i.removeAllRanges(),i.addRange(m)}catch{}},setValueWithCaret:te,getLogicalRangeRect:ne,setValue:c=>{p(H(c)),e.focus(),g(c.length,{focus:!0}),C()},replaceLogicalRange:oe,insertMentionAtTrigger:re,insertMentionAtSelection:ie,setMentionStatus:se,submit:()=>G(e.closest("form")),dispatchInput:C,focus:()=>e.focus(),destroy:()=>{e.removeEventListener("input",F),e.removeEventListener("compositionstart",V),e.removeEventListener("compositionend",q),e.removeEventListener("paste",j),e.removeEventListener("beforeinput",$)}}}var me=0,pe=()=>`pmention-${++me}`;function fe(t,n){n.className=`${t.className} persona-composer-contenteditable`.trim();for(let r=0;r<t.style.length;r++){let l=t.style.item(r);l!=="height"&&n.style.setProperty(l,t.style.getPropertyValue(l),t.style.getPropertyPriority(l))}let o=t.getAttribute("placeholder");o&&(n.setAttribute("data-placeholder",o),n.setAttribute("aria-placeholder",o));let e=t.getAttribute("aria-label")??o;e&&n.setAttribute("aria-label",e)}function ge(t,n,o){Object.defineProperty(t,"value",{configurable:!0,get:()=>n.getValue(),set:e=>{n.setValueWithCaret(e,e.length),n.dispatchInput()}}),Object.defineProperty(t,"placeholder",{configurable:!0,get:()=>t.getAttribute("data-placeholder")??"",set:e=>{e?(t.setAttribute("data-placeholder",e),t.setAttribute("aria-placeholder",e),o||t.setAttribute("aria-label",e)):(t.removeAttribute("data-placeholder"),t.removeAttribute("aria-placeholder"),o||t.removeAttribute("aria-label"))}}),Object.defineProperty(t,"selectionStart",{configurable:!0,get:()=>n.getSelection().start}),Object.defineProperty(t,"selectionEnd",{configurable:!0,get:()=>n.getSelection().end}),t.setSelectionRange=(e,r)=>n.setSelection(e??0,r??e??0)}function be(t){let{textarea:n}=t,o={generateId:pe,renderToken:t.renderToken,onMentionRemoved:t.onMentionRemoved,placeholder:n.getAttribute("placeholder")??void 0},e=ee(o),r=e.element,l=n.getAttribute("aria-label")!=null;fe(n,r),ge(r,e,l),r.getInlineMessageFields=()=>Y(e.getDocument?.()??{blocks:[]});let u=n.selectionStart??n.value.length;return e.setValueWithCaret(n.value,u),{input:e,element:r,destroy:e.destroy}}export{be as mountInlineComposer};
|