import * as React from 'react'; import { LexicalEditor } from 'lexical'; import { a as DemoSpeed, b as DemoTrigger } from './types-DUwnWaxR.mjs'; /** * Composer — the generic text composition surface for the design system. * * The answer wherever a user is composing a message: AI chat input, * comment thread reply, post-body editor, future copilot panels. * Replaces the textarea-with-buttons pattern that hosts kept rolling * by hand. * * Built on Lexical (Meta's React-first editor framework) so it can do: * - rich text formatting (B / I / U / S / code, headings, blockquote, * pullquote, lists) * - mentions and slash commands via lexical-beautiful-mentions, with * a typeahead popover and theme-able tokens * - image attachments (paperclip + clipboard paste) when opted in * - scripted demo playback for marketing surfaces (types text, opens * mention popovers, applies formatting, all via the same step * vocabulary as ) * * Slot-based composition for the action row: hosts that need custom * affordances (template picker, voice button, attach-document) pass * `leftActions` / `rightActions`. Default Send / Stop / paperclip * render only when the host hasn't replaced the slot. * * Hosts that want the canned "chat composer with paperclip + send" * preset should reach for `` instead, which configures * this Composer with the right slots wired up. * * Scripted demos: same `speed` / `trigger` / `play` / `loop` vocabulary * as ``, sharing the underlying `useScriptedDemo` hook from * `lib/demo/`. The Composer adds its own verbs (`mention`, `format`, * `select`, `submit`) on top of the universal `type` / `wait` / `clear`. */ type ComposerFormat = "bold" | "italic" | "underline" | "strikethrough" | "code" | "h1" | "h2" | "h3" | "blockquote" | "pullquote" | "ul" | "ol"; interface ComposerMentionItem { id: string; /** Display value (without the trigger char). */ value: string; /** Optional secondary label shown in the suggester. */ label?: string; /** Avatar URL or initials for the suggester row. */ avatar?: string; /** Arbitrary payload the host can attach to the mention. */ data?: Record; } interface ComposerTriggerConfig { /** The trigger character, eg. "@" or "/". */ char: string; /** * Items to populate the suggester. Either a static array or a * resolver function (sync or async) that receives the typed query. * The plugin filters automatically when items is an array. */ items: ComposerMentionItem[] | ((query: string) => ComposerMentionItem[] | Promise); /** * Whether to strip the trigger char on insert. Defaults: keep for * "@" (mentions read as "@alice"), strip for "/" (commands read as * "Insert image" not "/insert-image"). */ stripTrigger?: boolean; } interface ComposerAttachmentConfig { /** Master enable. Set true on the prop to use defaults, or pass a config object. */ enabled?: boolean; /** HTML accept attribute on the file input. Default "image/*". */ accept?: string; /** Max number of attachments. Default 10. */ maxItems?: number; /** Allow multiple selection in the file picker. Default true. */ multiple?: boolean; } interface ComposerAttachment { id: string; file: File; /** Object URL owned by the composer. Hosts must NOT revoke it. */ previewUrl: string; name: string; } interface ComposerContent { /** Plain text representation of the editor contents (whitespace preserved). */ text: string; /** Lexical editor state serialised to JSON (for round-trip persistence). */ json: string; /** Resolved mention tokens in document order. */ mentions: Array<{ trigger: string; value: string; data?: Record; }>; } interface ComposerHandle { /** Run a demo script imperatively (vs. via `steps` + `trigger="manual"`). */ play: (steps: ComposerStep[]) => void; /** Cancel an in-flight demo. Idempotent. */ stop: () => void; /** * One-shot replay of the configured `steps`. Cancels any in-flight * run, clears the editor, replays from step 0. Pass a delay (ms) to * schedule the replay (useful for chaining demos). Requires `steps` * to be configured. */ restart: (delayMs?: number) => void; /** Move focus into the editor. */ focus: () => void; /** Wipe the editor. */ clear: () => void; /** Insert plain text at the current selection. */ insert: (text: string) => void; /** Snapshot the current content + mentions. */ getContent: () => ComposerContent; /** Direct access to the underlying Lexical editor (escape hatch). */ getEditor: () => LexicalEditor | null; } /** * Demo step vocabulary for Composer scripts. Shares `type` / `wait` / * `clear` with the universal `lib/demo` verbs; adds composer-specific * `mention`, `format`, `select`, `newline`, `submit` on top. */ type ComposerStep = { type: "type"; text: string; speed?: DemoSpeed; } | { type: "wait"; ms: number; } | { type: "clear"; } | { type: "newline"; } | { type: "submit"; } | { type: "mention"; /** Trigger char (must match a registered ComposerTriggerConfig.char). */ trigger: string; /** Value to insert (without the trigger). Looks up the matching item by `value`. */ value: string; /** Optional pre-typed query — the demo types this after the trigger char before "selecting" the value, to show the typeahead in action. */ query?: string; } | { type: "format"; format: ComposerFormat; } | { type: "select"; /** Substring to find and select. First match wins. */ text: string; }; interface ComposerProps { /** Placeholder copy shown when empty. */ placeholder?: string; /** Initial plain text content. For richer initial state, use `initialJson`. */ initialText?: string; /** Initial Lexical state JSON (from a previous `onSubmit` round-trip). */ initialJson?: string; /** * Available formats. Pass false to disable rich text entirely * (plain text mode, half the bundle weight, no toolbar). Default * enables a sensible set for most chat / comment surfaces. */ formats?: ComposerFormat[] | false; /** * Render the formatting toolbar. Default false because most uses * are short-form. Set true (or "top") to show the toolbar above the * editor. "floating" is planned; not yet implemented. */ toolbar?: boolean | "top"; /** * Mention / slash command configs. Each entry registers one trigger * char and its items. Pass `[{ char: "@", items: people }, { char: "/", items: commands }]` * for the common chat-app setup. */ triggers?: ComposerTriggerConfig[]; /** * Image attachments (paperclip + clipboard paste). Pass true for * defaults, an object to customise, or omit/false to skip the * attachment plumbing entirely. */ attachments?: boolean | ComposerAttachmentConfig; /** Fires when the user submits (Enter, click Send, or scripted `submit` step). */ onSubmit?: (content: ComposerContent, attachments?: ComposerAttachment[]) => void; /** * Fires on every editor change with the current plain text. Use for * length validation, controlled-value bridges (eg. AIChatComposer * forwarding to a host's `value`/`onChange` pair), or live preview * surfaces. Cheap, called frequently; debounce if you need the * Lexical state JSON (use `getContent()` via ref instead). */ onChange?: (text: string) => void; /** * Loading state — disables the editor + paperclip and swaps the * default Send button for Stop. Has no effect when `rightActions` * overrides the default Send. */ isLoading?: boolean; /** Stop handler — required for Stop to be active when loading. */ onStop?: () => void; /** Hard character cap. */ maxLength?: number; /** Auto-focus the editor on mount. Default false. */ autoFocus?: boolean; /** Whether Enter submits. Default true (Shift-Enter still inserts a newline). */ submitOnEnter?: boolean; /** * Custom content for the left action slot. Replaces the default * paperclip button when `attachments` is enabled. */ leftActions?: React.ReactNode; /** * Custom content for the right action slot. Replaces the default * Send / Stop button. Use the `useComposer()` hook inside to access * imperative methods. */ rightActions?: React.ReactNode; /** Hide the default Send button without replacing it. */ hideSend?: boolean; /** Scripted demo steps. */ steps?: ComposerStep[]; /** What kicks the script off. Defaults to "mount". */ trigger?: DemoTrigger; /** For trigger="manual" — flip true to play. */ play?: boolean; /** Animation feel. */ speed?: DemoSpeed; /** Loop the script forever. */ loop?: boolean; /** * Pause between loop iterations (ms). Defaults to 2000. Marketing * heroes that want the demo to breathe between repeats bump this * higher; tight inline demos drop it. */ loopDelay?: number; /** * Fires once per loop cycle, AFTER the loopDelay pause and BEFORE * the script replays. Use to reset parent state that the script * mutated via onSubmit (e.g., wipe a messages list back to its * seed before the demo types into it again). The editor is cleared * automatically — you only need this hook if state outside the * Composer needs to reset too. */ onLoopReset?: () => void; /** * Bare mode — strip the card chrome (border / bg / rounding). Use * when embedding inside an existing card or column layout. */ bare?: boolean; /** * Read-only mode — disables editing AND focusability. Programmatic * updates (including scripted demo playback) still work. Use for * marketing surfaces that render a Composer purely for show, so the * scripted typing doesn't steal focus from other inputs on the page. * Hides the default Send / paperclip action row. */ readOnly?: boolean; className?: string; } declare const Composer: React.ForwardRefExoticComponent>; declare const ComposerReply: React.ForwardRefExoticComponent>; export { Composer, type ComposerAttachment, type ComposerAttachmentConfig, type ComposerContent, type ComposerFormat, type ComposerHandle, type ComposerMentionItem, type ComposerProps, ComposerReply, type ComposerStep, type ComposerTriggerConfig };