UNPKG

@kitn.ai/ui

Version:

Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.

87 lines (86 loc) 3.6 kB
import { JSX } from 'solid-js'; import { ComposerDoc, EntityRef } from '../primitives/composer-model'; export interface TriggerItem { id: string; label: string; icon?: string; /** Secondary muted text shown beside the label in the menu (Codex-style). */ description?: string; /** Section header to group this item under in the menu (e.g. 'Plugins', 'Agents'). */ group?: string; /** Entity kind for the inserted pill; overrides the trigger's default `kind` so * one trigger can mix kinds across sections (e.g. agents + plugins under `@`). */ kind?: string; promptText?: string; data?: Record<string, unknown>; } export interface TriggerDef { char: string; kind: string; items?: TriggerItem[]; } export type HighlightRule = string | { pattern: string; flags?: string; class?: string; }; export interface ComposerChange { doc: ComposerDoc; text: string; entities: EntityRef[]; } /** Imperative handle exposed via `controllerRef` — surfaces the composer's latent * capabilities (focus/blur the editable, clear the doc, submit, insert a pill) so * the `<kai-composer>` facade can forward them as instance methods. */ export interface ComposerController { focus(options?: FocusOptions): void; blur(): void; clear(): void; send(): void; insertEntity(entity: EntityRef): void; } export interface ComposerProps { value?: string | ComposerDoc; placeholder?: string; disabled?: boolean; loading?: boolean; maxHeight?: number | string; submitOnEnter?: boolean; triggers?: TriggerDef[]; highlights?: HighlightRule[]; /** Default icon per entity kind (kind → image URL/data-URI), shown on a pill + * menu item when the item has no `icon` of its own. Overrides the built-in * glyphs (agent/plugin). Example: `{ agent: '/icons/bot.svg' }`. */ kindIcons?: Record<string, string>; /** Render WITHOUT the rounded frame/background/padding — just the editable + * placeholder + menu. For embedding inside another frame (e.g. PromptInput). */ bare?: boolean; /** Override the editable element's classes (used in `bare` mode to match an * existing input's exact look). The placeholder mirrors these for alignment. */ editableClass?: string; /** Accessible name for the editable (role=textbox). Falls back to the * placeholder, then "Message input". */ ariaLabel?: string; /** Receive the editable element (e.g. to register it for click-to-focus). */ editableRef?: (el: HTMLDivElement) => void; /** Receive the imperative controller once mounted. The `<kai-composer>` facade * forwards these as element methods (focus/blur/clear/send/insertEntity). */ controllerRef?: (controller: ComposerController) => void; onChange?: (change: ComposerChange) => void; onSubmit?: (change: ComposerChange) => void; onTrigger?: (info: { char: string; query: string; rect: DOMRect; }) => void; onTriggerClose?: () => void; onEntityAdd?: (entity: EntityRef) => void; onEntityRemove?: (entity: EntityRef) => void; /** The editable gained focus. `focus`/`blur` are NOT composed, so they don't * escape the shadow root — this re-exposes them. (keydown/paste/focusin/focusout * are composed and already reach the host as native events; no wrapper needed.) */ onFocus?: (e: FocusEvent) => void; /** The editable lost focus. */ onBlur?: (e: FocusEvent) => void; } export declare function Composer(props: ComposerProps): JSX.Element;