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.

1,160 lines 294 kB
[ { "tag": "kai-agent-card", "className": "KaiAgentCardElement", "displayName": "AgentCard", "props": [ { "name": "name", "type": "undefined | string", "optional": true, "scalar": true, "description": "The agent's name — the primary label. Attribute: `name`.", "displayType": "undefined | string" }, { "name": "active", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Selected / focused state: highlighted border + surface. Attribute: `active`.", "displayType": "undefined | false | true" }, { "name": "needsAttention", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Raise a prominent \"Needs you\" pill plus a glowing amber edge — the attention-routing signal that pulls focus to this agent. Attribute: `needs-attention`.", "displayType": "undefined | false | true" }, { "name": "status", "type": "undefined | { tone: \"working\" | \"idle\" | \"done\" | \"error\" | \"blocked\"; label?: undefined | string; pulse?: undefined | false | true }", "optional": true, "scalar": false, "description": "Run status — a JS PROPERTY (object), not an attribute. Shape: `{ tone, label?, pulse? }`, where `tone` is one of `working` | `idle` | `done` | `error` | `blocked` (maps to the kit's tool hues), `label` is an optional short string beside the dot, and `pulse` animates the dot. Set it with `el.status = { tone: 'working', label: 'Working', pulse: true }`.", "displayType": "undefined | { tone: \"working\" | \"idle\" | \"done\" | \"error\" | \"blocked\"; label?: undefined | string; pulse?: undefined | false | true }" } ], "events": [ { "name": "kai-activate", "detail": null, "description": "The card was activated — clicked, or Enter / Space while focused. Promote this agent back to focus.", "displayDetail": null }, { "name": "kai-menu", "detail": null, "description": "The trailing \"...\" kebab was clicked. The consumer opens its own menu; the card only surfaces the affordance (the click does not also activate the card).", "displayDetail": null } ], "methods": [], "composedFrom": [ { "name": "AgentCard", "group": "UI", "storyId": "solid-advanced-primitives-agentcard--docs" } ], "tokens": [], "parts": [ { "name": "status", "doc": "The leading tone-colored status dot.", "recipe": "kai-agent-card::part(status) { width: 0.625rem; height: 0.625rem }" }, { "name": "menu", "doc": "The trailing overflow (\"...\") menu button.", "recipe": "kai-agent-card::part(menu) { opacity: 1 }" } ] }, { "tag": "kai-artifact", "className": "KaiArtifactElement", "displayName": "Artifact", "props": [ { "name": "src", "type": "undefined | string", "optional": true, "scalar": true, "description": "URL the preview iframe frames. Consumer-controlled.", "displayType": "undefined | string" }, { "name": "files", "type": "{ path: string; url?: undefined | string; code?: undefined | string; language?: undefined | string; type?: undefined | \"html\" | \"pdf\" | \"image\" | \"other\"; additions?: undefined | number; deletions?: undefined | number; status?: undefined | \"added\" | \"modified\" | \"deleted\" | \"renamed\" | \"untracked\" }[]", "optional": false, "scalar": false, "description": "Files for the Code tab tree + each file's preview `url`. Set as a JS property (array).", "typeName": "FileTreeFile[]", "typeShape": "{ path: string; url?: undefined | string; code?: undefined | string; language?: undefined | string; type?: undefined | \"html\" | \"pdf\" | \"image\" | \"other\"; additions?: undefined | number; deletions?: undefined | number; status?: undefined | \"added\" | \"modified\" | \"deleted\" | \"renamed\" | \"untracked\" }[]", "default": "[]", "typeImport": "FileTreeFile", "displayType": "{ path: string; url?: undefined | string; code?: undefined | string; language?: undefined | string; type?: undefined | \"html\" | \"pdf\" | \"image\" | \"other\"; additions?: undefined | number; deletions?: undefined | number; status?: undefined | \"added\" | \"modified\" | \"deleted\" | \"renamed\" | \"untracked\" }[]" }, { "name": "tab", "type": "undefined | \"preview\" | \"code\"", "optional": true, "scalar": true, "description": "Controlled active tab: `preview` or `code`. When set, the artifact follows it (re-asserted on change). Leave unset for an uncontrolled tab (see `defaultTab`).", "displayType": "undefined | \"preview\" | \"code\"" }, { "name": "defaultTab", "type": "undefined | \"preview\" | \"code\"", "optional": true, "scalar": true, "description": "Uncontrolled INITIAL tab (used only when `tab` is unset). Default `preview`. Seeds the starting tab; the user can then switch freely without the consumer re-asserting a controlled `tab`.", "displayType": "undefined | \"preview\" | \"code\"" }, { "name": "activeFile", "type": "undefined | string", "optional": true, "scalar": true, "description": "Selected file path — syncs the tree highlight, Code source, and preview.", "displayType": "undefined | string" }, { "name": "sandbox", "type": "undefined | string", "optional": true, "scalar": true, "description": "iframe `sandbox` override. Secure default `allow-scripts allow-forms` (NOT `allow-same-origin`).", "default": "'allow-scripts allow-forms'", "displayType": "undefined | string" }, { "name": "iframeTitle", "type": "undefined | string", "optional": true, "scalar": true, "description": "Accessible title for the preview iframe.", "displayType": "undefined | string" }, { "name": "maximized", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Reflects the artifact's own maximized view-state (usually driven by the protocol).", "default": "false", "displayType": "undefined | false | true" }, { "name": "expandable", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Show the expand-to-fill button (OPT-IN).", "default": "false", "displayType": "undefined | false | true" }, { "name": "openInTab", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Show the open-in-new-tab button (OPT-IN).", "default": "false", "displayType": "undefined | false | true" }, { "name": "noNav", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Hide back/forward.", "default": "false", "displayType": "undefined | false | true" }, { "name": "noReload", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Hide reload.", "default": "false", "displayType": "undefined | false | true" }, { "name": "noHome", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Hide home.", "default": "false", "displayType": "undefined | false | true" }, { "name": "noPathField", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Hide the address field.", "default": "false", "displayType": "undefined | false | true" }, { "name": "noTabs", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Hide the Preview|Code toggle.", "default": "false", "displayType": "undefined | false | true" }, { "name": "standalone", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Standalone chrome: rounded corners + border (else square, borderless in-panel).", "default": "false", "displayType": "undefined | false | true" }, { "name": "readonlyPath", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Show the address but make it read-only (visible, nav-tracking, non-editable).", "default": "false", "displayType": "undefined | false | true" }, { "name": "displayUrl", "type": "undefined | string", "optional": true, "scalar": true, "description": "Friendly address shown in the path field instead of the real current url (read-only, non-navigable). Use when the framed url is not consumer-facing (e.g. a `data:` blob) so a clean address shows instead of leaking it. Scalar string: set as the `display-url` attribute or the `displayUrl` property.", "displayType": "undefined | string" } ], "events": [ { "name": "kai-file-select", "detail": "{ path: string }", "description": "Fired when a file is selected. `detail.path`.", "displayDetail": "{ path: string }" }, { "name": "kai-maximize-change", "detail": "{ maximized: false | true }", "description": "Artifact's own maximize button toggled (consumer-observable; non-bubbling).", "displayDetail": "{ maximized: false | true }" }, { "name": "kai-navigate", "detail": "{ url: string }", "description": "Fired when the preview navigates. `detail.url` = the new location.", "displayDetail": "{ url: string }" }, { "name": "kai-tab-change", "detail": "{ tab: \"preview\" | \"code\" }", "description": "Fired when the Preview|Code tab changes. `detail.tab`.", "displayDetail": "{ tab: \"preview\" | \"code\" }" } ], "methods": [ { "name": "back", "params": "", "returns": "void", "description": "Go back in the artifact's own history stack (no-op when there's no prior entry)." }, { "name": "forward", "params": "", "returns": "void", "description": "Go forward in the history stack (no-op when there's no forward entry)." }, { "name": "reload", "params": "", "returns": "void", "description": "Force-reload the current preview url (also re-renders an inline PDF)." }, { "name": "home", "params": "", "returns": "void", "description": "Navigate to the `src` home url (no-op when there's no `src`)." }, { "name": "navigate", "params": "url: string", "returns": "void", "description": "Push + load a url in the preview — the path-field submit path (fires kai-navigate)." }, { "name": "selectFile", "params": "path: string", "returns": "void", "description": "Select a file by path: highlights the tree, shows its source, navigates the preview (fires kai-file-select + kai-navigate). Named selectFile to avoid the `activeFile` prop." }, { "name": "openExternal", "params": "", "returns": "void", "description": "Open the current url in a new browser tab (no-op when there's no concrete url). Named openExternal, NOT openInTab — that's a prop (toolbar button visibility)." }, { "name": "maximize", "params": "", "returns": "void", "description": "Enter the maximized view-state (fires kai-maximize-change{maximized:true}). Named maximize, NOT maximized — that's a prop." }, { "name": "restore", "params": "", "returns": "void", "description": "Exit the maximized view-state (fires kai-maximize-change{maximized:false})." } ], "composedFrom": [ { "name": "Artifact", "group": "Components", "storyId": "solid-advanced-elements-artifact--docs" } ], "tokens": [] }, { "tag": "kai-attachments", "className": "KaiAttachmentsElement", "displayName": "Attachments", "props": [ { "name": "items", "type": "{ id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]", "optional": false, "scalar": false, "description": "The attachments to render. Set as a JS property (array).", "typeName": "AttachmentData[]", "typeShape": "{ id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]", "default": "[]", "typeImport": "AttachmentData", "displayType": "AttachmentData[]" }, { "name": "variant", "type": "undefined | \"grid\" | \"inline\" | \"list\"", "optional": true, "scalar": true, "description": "Layout: `grid` = visual tiles, `inline` = icon + label chips, `list` = rows.", "default": "'grid'", "displayType": "undefined | \"grid\" | \"inline\" | \"list\"" }, { "name": "hoverCard", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Wrap each item in a hover card that previews its details.", "default": "false", "displayType": "undefined | false | true" }, { "name": "removable", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Show a remove button per item; clicking it fires a `kai-remove` event.", "default": "false", "displayType": "undefined | false | true" }, { "name": "showMediaType", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Also show the media type beneath the filename (non-grid variants).", "default": "false", "displayType": "undefined | false | true" }, { "name": "emptyText", "type": "undefined | string", "optional": true, "scalar": true, "description": "Text shown when `items` is empty.", "displayType": "undefined | string" } ], "events": [ { "name": "kai-remove", "detail": "{ id: string }", "description": "A remove button was clicked.", "displayDetail": "{ id: string }" } ], "methods": [], "composedFrom": [ { "name": "Attachments", "group": "Components", "storyId": "solid-advanced-elements-attachments--docs" }, { "name": "Attachment", "group": "Components", "storyId": "solid-advanced-elements-attachment--docs" }, { "name": "AttachmentPreview", "group": "Components", "storyId": "solid-advanced-elements-attachmentpreview--docs" }, { "name": "AttachmentInfo", "group": "Components", "storyId": "solid-advanced-elements-attachmentinfo--docs" }, { "name": "AttachmentRemove", "group": "Components", "storyId": "solid-advanced-elements-attachmentremove--docs" }, { "name": "AttachmentHoverCard", "group": "Components", "storyId": "solid-advanced-elements-attachmenthovercard--docs" }, { "name": "AttachmentHoverCardTrigger", "group": "Components", "storyId": "solid-advanced-elements-attachmenthovercardtrigger--docs" }, { "name": "AttachmentHoverCardContent", "group": "Components", "storyId": "solid-advanced-elements-attachmenthovercardcontent--docs" }, { "name": "AttachmentEmpty", "group": "Components", "storyId": "solid-advanced-elements-attachmentempty--docs" } ], "tokens": [], "parts": [ { "name": "preview", "doc": "The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card — raise or lower the cap from outside.", "recipe": "kai-attachments::part(preview) { max-width: 32rem; max-height: 24rem }" } ] }, { "tag": "kai-avatar", "className": "KaiAvatarElement", "displayName": "Avatar", "props": [ { "name": "src", "type": "undefined | string", "optional": true, "scalar": true, "description": "Image URL/data-URI. When absent, the `fallback` initials show instead.", "displayType": "undefined | string" }, { "name": "alt", "type": "undefined | string", "optional": true, "scalar": true, "description": "Alt text for the image. Defaults to `fallback`.", "displayType": "undefined | string" }, { "name": "fallback", "type": "undefined | string", "optional": true, "scalar": true, "description": "Short text shown when there's no image — usually initials (e.g. \"JD\", \"AI\").", "default": "''", "displayType": "undefined | string" }, { "name": "size", "type": "undefined | \"sm\" | \"md\" | \"lg\"", "optional": true, "scalar": true, "description": "Size token: `sm` | `md` (default) | `lg`.", "default": "'md'", "displayType": "undefined | \"sm\" | \"md\" | \"lg\"" } ], "events": [], "methods": [], "composedFrom": [ { "name": "Avatar", "group": "UI", "storyId": "solid-advanced-primitives-avatar--docs" } ], "tokens": [] }, { "tag": "kai-badge", "className": "KaiBadgeElement", "displayName": "Badge", "props": [ { "name": "variant", "type": "undefined | \"default\" | \"count\" | \"citation\"", "optional": true, "scalar": true, "description": "`default` (muted pill) · `count` (compact number badge) · `citation` (filled primary, for inline citation markers). Defaults to `default`.", "default": "'default'", "displayType": "undefined | \"default\" | \"count\" | \"citation\"" } ], "events": [], "methods": [], "composedFrom": [ { "name": "Badge", "group": "UI", "storyId": "solid-advanced-primitives-badge--docs" } ], "tokens": [], "parts": [ { "name": "badge", "doc": "The badge pill. Restyle its background, color, or shape; the `variant` prop (default/count/citation) sets the defaults.", "recipe": "kai-badge::part(badge) { background: var(--color-primary); color: var(--color-primary-foreground) }" } ] }, { "tag": "kai-button", "className": "KaiButtonElement", "displayName": "Button", "props": [ { "name": "variant", "type": "undefined | \"default\" | \"subtle\" | \"ghost\" | \"outline\" | \"destructive\"", "optional": true, "scalar": true, "description": "Visual style. `default` (filled), `subtle` (muted text, hover tint — the toolbar icon look), `ghost` (transparent, hover fill), `outline`, or `destructive`. Defaults to `default`.", "default": "'default'", "displayType": "undefined | \"default\" | \"subtle\" | \"ghost\" | \"outline\" | \"destructive\"" }, { "name": "size", "type": "undefined | \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\"", "optional": true, "scalar": true, "description": "Size token. `icon` / `icon-sm` are square (for icon-only buttons); `sm` / `md` / `lg` size text buttons. Defaults to `md`.", "default": "'md'", "displayType": "undefined | \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\"" }, { "name": "icon", "type": "undefined | string", "optional": true, "scalar": true, "description": "Leading icon: a named icon (e.g. `\"mic\"`, `\"plus\"`), an image URL/data-URI, or plain text. Renders before any slotted label.", "displayType": "undefined | string" }, { "name": "iconTrailing", "type": "undefined | string", "optional": true, "scalar": true, "description": "Trailing icon, after the label (e.g. `\"chevron-down\"` for a menu affordance).", "displayType": "undefined | string" }, { "name": "label", "type": "undefined | string", "optional": true, "scalar": true, "description": "Accessible name. REQUIRED for icon-only buttons (no visible text); ignored when you slot visible text, which already names the button.", "displayType": "undefined | string" }, { "name": "disabled", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Disable the button (non-interactive, dimmed).", "default": "false", "displayType": "undefined | false | true" }, { "name": "full", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Stretch the button to the full width of its container (a block button) — e.g. a card CTA or a stacked action. Attribute: `full`.", "default": "false", "displayType": "undefined | false | true" }, { "name": "align", "type": "undefined | \"start\" | \"center\" | \"end\"", "optional": true, "scalar": true, "description": "Justify the button's content: `start`, `center` (default), or `end`. Combine with `full` for a full-width, left-aligned button.", "default": "'center'", "displayType": "undefined | \"start\" | \"center\" | \"end\"" }, { "name": "type", "type": "undefined | \"button\" | \"submit\" | \"reset\"", "optional": true, "scalar": true, "description": "Native button `type`. Defaults to `button` (so it never submits a form).", "default": "'button'", "displayType": "undefined | \"button\" | \"submit\" | \"reset\"" } ], "events": [ { "name": "kai-click", "detail": null, "description": "The button was activated (pointer or keyboard). Carries no detail. The native `click` also bubbles (composed) for consumers who prefer it.", "displayDetail": null } ], "methods": [ { "name": "focus", "params": "options?: FocusOptions", "returns": "void", "description": "Focus the inner `<button>` (host.focus() would focus the wrapper)." }, { "name": "blur", "params": "", "returns": "void", "description": "Blur the inner `<button>`." }, { "name": "click", "params": "", "returns": "void", "description": "Programmatically activate the button — runs the same path as a user click and fires kai-click. Forwarding to the inner button means `disabled` is respected automatically." } ], "composedFrom": [ { "name": "Button", "group": "UI", "storyId": "solid-advanced-primitives-button--docs" } ], "tokens": [], "slots": [ { "name": "icon", "mode": "replace", "doc": "A custom leading icon (any inline SVG, inherits `currentColor`). Wins over the `icon` prop." } ], "parts": [ { "name": "button", "doc": "The button element. Restyle radius, padding, colors, or weight from outside; the `variant`/`size` props set the defaults.", "recipe": "kai-button::part(button) { border-radius: 9999px; font-weight: 600 }" } ] }, { "tag": "kai-card", "className": "KaiCardElement", "displayName": "Card", "props": [ { "name": "appearance", "type": "undefined | \"outlined\" | \"filled\" | \"plain\" | \"accent\"", "optional": true, "scalar": true, "description": "Surface treatment: `outlined` (default) | `filled` | `plain` | `accent`. Attribute: `appearance`.", "default": "'outlined'", "displayType": "undefined | \"outlined\" | \"filled\" | \"plain\" | \"accent\"" }, { "name": "orientation", "type": "undefined | \"vertical\" | \"horizontal\" | \"responsive\"", "optional": true, "scalar": true, "description": "`vertical` (default, media on top) | `horizontal` (media at the start) | `responsive` (horizontal when the card's container is wide enough, else vertical — a container query on the card's own width). Attribute: `orientation`.", "default": "'vertical'", "displayType": "undefined | \"vertical\" | \"horizontal\" | \"responsive\"" }, { "name": "collapse", "type": "undefined | string", "optional": true, "scalar": true, "description": "The card width below which a `responsive` card collapses to vertical and the footer actions stack. A CSS length; default `28rem`. Attribute: `collapse`.", "default": "'28rem'", "displayType": "undefined | string" }, { "name": "dense", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Tighter spacing for dense lists. Attribute: `dense`.", "default": "false", "displayType": "undefined | false | true" }, { "name": "dismissible", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Show a close (×) that hides the card and emits `kai-dismiss`. Attribute: `dismissible`. Off by default.", "default": "false", "displayType": "undefined | false | true" }, { "name": "href", "type": "undefined | string", "optional": true, "scalar": true, "description": "Render the whole card as a link. Attribute: `href`. Wins over `clickable`.", "displayType": "undefined | string" }, { "name": "target", "type": "undefined | string", "optional": true, "scalar": true, "description": "`target` for the `href` anchor. Attribute: `target`.", "displayType": "undefined | string" }, { "name": "rel", "type": "undefined | string", "optional": true, "scalar": true, "description": "`rel` for the `href` anchor. Attribute: `rel`.", "displayType": "undefined | string" }, { "name": "clickable", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Make the whole card a button (`role=\"button\"`, Enter/Space, hover affordance) that emits `kai-card-click`. Attribute: `clickable`. Ignored when `href` is set.", "default": "false", "displayType": "undefined | false | true" } ], "events": [ { "name": "kai-card-click", "detail": null, "description": "A `clickable`/`href` card was activated (click, or Enter/Space).", "displayDetail": null }, { "name": "kai-dismiss", "detail": null, "description": "The card was dismissed via its × (it also hides itself).", "displayDetail": null } ], "methods": [], "composedFrom": [ { "name": "Card", "group": "UI", "storyId": "solid-advanced-primitives-card--docs" } ], "tokens": [], "slots": [ { "name": "media", "mode": "inject", "doc": "Full-bleed media (image/video/illustration) at the top (vertical) or start (horizontal). Clipped to the card corners." }, { "name": "header", "mode": "inject", "doc": "Header content, e.g. a title. Rendered above the body." }, { "name": "header-actions", "mode": "inject", "doc": "An actions cluster pinned to the end of the header row." }, { "name": "footer", "mode": "inject", "doc": "Footer content rendered below the body." }, { "name": "footer-actions", "mode": "inject", "doc": "Action buttons pinned to the end of the footer. Do NOT combine with a clickable/href card (nested interactive)." } ], "parts": [ { "name": "card", "doc": "The card root (a div, or an a when href is set). Restyle its radius, border, or background; set --kai-card-spacing for padding/gaps (the dense prop sets the compact default).", "recipe": "kai-card::part(card) { border-radius: 1rem; --kai-card-spacing: 1.5rem }" }, { "name": "media", "doc": "The full-bleed media region. Cap or crop it from outside (e.g. a fixed height with object-fit).", "recipe": "kai-card::part(media) { max-height: 12rem }" }, { "name": "header", "doc": "The header row (header content + header-actions). Add a divider or adjust its alignment.", "recipe": "kai-card::part(header) { border-bottom: 1px solid var(--color-border) }" }, { "name": "body", "doc": "The default-slot body region.", "recipe": "kai-card::part(body) { font-size: 0.9375rem }" }, { "name": "footer", "doc": "The footer row (footer content + footer-actions).", "recipe": "kai-card::part(footer) { border-top: 1px solid var(--color-border) }" }, { "name": "dismiss", "doc": "The dismiss (×) button shown when dismissible. Recolor or reposition it from outside.", "recipe": "kai-card::part(dismiss) { color: var(--color-muted-foreground) }" } ] }, { "tag": "kai-cards", "className": "KaiCardsElement", "displayName": "Cards", "props": [ { "name": "cards", "type": "undefined | { type: string; id: string; data: unknown; title?: undefined | string; resolution?: undefined | { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }[]", "optional": true, "scalar": false, "description": "The stream of card envelopes to render. Set as a JS PROPERTY: `el.cards = [...]`.", "displayType": "undefined | { type: string; id: string; data: unknown; title?: undefined | string; resolution?: undefined | { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }[]" }, { "name": "types", "type": "undefined | Record<string, string>", "optional": true, "scalar": false, "description": "Optional type→tag overrides/additions (merged over the built-ins). Property: `el.types`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type.", "displayType": "undefined | Record<string, string>" }, { "name": "policy", "type": "undefined | { onSubmit?: undefined | (cardId: string, data: unknown) => void; onAction?: undefined | (cardId: string, action: string, payload?: unknown) => void; onSendPrompt?: undefined | (text: string, opts: { mode: \"compose\" | \"send\"; context?: unknown; }) => void; onOpen?: undefined | (url: string, target: \"tab\" | \"artifact\") => void; onState?: undefined | (cardId: string, patch: unknown) => void; onDismiss?: undefined | (cardId: string) => void; onReopen?: undefined | (cardId: string) => void; onError?: undefined | (cardId: string, message: string) => void; maxSendPromptMode?: undefined | \"compose\" | \"send\" }", "optional": true, "scalar": false, "description": "Optional CardPolicy handling child events. Property: `el.policy`.", "displayType": "undefined | { onSubmit?: undefined | (cardId: string, data: unknown) => void; onAction?: undefined | (cardId: string, action: string, payload?: unknown) => void; onSendPrompt?: undefined | (text: string, opts: { mode: \"compose\" | \"send\"; context?: unknown; }) => void; onOpen?: undefined | (url: string, target: \"tab\" | \"artifact\") => void; onState?: undefined | (cardId: string, patch: unknown) => void; onDismiss?: undefined | (cardId: string) => void; onReopen?: undefined | (cardId: string) => void; onError?: undefined | (cardId: string, message: string) => void; maxSendPromptMode?: undefined | \"compose\" | \"send\" }" } ], "events": [ { "name": "kai-card-resolved", "detail": "{ cardId: string; resolution: { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }", "description": "A child card transitioned to a resolved/deferred state (an action was chosen, a form/tasks submission landed, or it was dismissed) — re-emitted off the host as a non-bubbling convenience event so a consumer can observe resolution centrally without diffing the cards array. `detail` = `{ cardId, resolution }`. (A `reopen` un-resolves a card and has no `CardResolution`, so it does NOT fire this — observe reopen via the underlying bubbling `kai-card` event.)", "displayDetail": "{ cardId: string; resolution: { kind: \"action\"; action: string; payload?: unknown; at?: undefined | string } | { kind: \"submit\"; data: unknown; at?: undefined | string } | { kind: \"dismissed\"; at?: undefined | string } | { kind: \"expired\"; reason?: undefined | string; at?: undefined | string } }" } ], "methods": [ { "name": "resolve", "params": "cardId: string, resolution: CardResolution", "returns": "void", "description": "Programmatically resolve a child card by id: set that envelope's `resolution` so the child re-renders into its read-only/resolved view — the imperative twin of the consumer mutating the cards array. No-op for an unknown id." }, { "name": "dismiss", "params": "cardId: string", "returns": "void", "description": "Collapse a card to its re-openable stub from the host side — convenience for `resolve(cardId, { kind: 'dismissed' })`." }, { "name": "getCard", "params": "cardId: string", "returns": "HTMLElement | null", "description": "Return the live child element node for a card id (or null) so consumers can call that card's own methods (focus/expand/…) without a shadow-DOM query." } ], "composedFrom": [ { "name": "CardFallback", "group": "Components", "storyId": "solid-advanced-elements-cardfallback--docs" } ], "tokens": [] }, { "tag": "kai-chain-of-thought", "className": "KaiChainOfThoughtElement", "displayName": "ChainOfThought", "props": [ { "name": "steps", "type": "{ label: string; content?: undefined | string; id?: undefined | string }[]", "optional": false, "scalar": false, "description": "The reasoning steps. Set as a JS property. Compound sub-parts collapse to this one data model (Route 1). Each `{ label, content?, id? }`.", "typeName": "ChainOfThoughtStepData[]", "typeShape": "{ label: string; content?: undefined | string; id?: undefined | string }[]", "default": "[]", "displayType": "{ label: string; content?: undefined | string; id?: undefined | string }[]" }, { "name": "type", "type": "undefined | \"single\" | \"multiple\"", "optional": true, "scalar": true, "description": "Open mode: `'multiple'` (default — any number of steps open at once) or `'single'` (at most one open; opening a step closes the others).", "displayType": "undefined | \"single\" | \"multiple\"" }, { "name": "value", "type": "undefined | string | string[]", "optional": true, "scalar": false, "description": "Controlled open step key(s). When set, it WINS over user interaction (the consumer owns the open set). String in `single` mode, string[] in `multiple` mode. Set as a JS property.", "displayType": "undefined | string | string[]" }, { "name": "defaultValue", "type": "undefined | string | string[]", "optional": true, "scalar": false, "description": "Uncontrolled INITIAL open step key(s) — seeds which steps render expanded. Ignored once `value` is provided. Set as a JS property.", "displayType": "undefined | string | string[]" } ], "events": [ { "name": "kai-value-change", "detail": "{ value: string | string[] }", "description": "The open set changed — by user click OR an expand()/collapse()/toggle() call. `value` is a string in `single` mode, a string[] in `multiple` mode. (Maps Radix Accordion's onValueChange.)", "displayDetail": "{ value: string | string[] }" } ], "methods": [ { "name": "expand", "params": "index?: number", "returns": "void", "description": "Open one step's detail by index, or — with no arg — ALL steps. In `single` mode opening one step closes the others (expand-all keeps the last)." }, { "name": "collapse", "params": "index?: number", "returns": "void", "description": "Close one step's detail by index, or — with no arg — ALL steps." }, { "name": "toggle", "params": "index?: number", "returns": "void", "description": "Flip one step's open state by index." } ], "composedFrom": [ { "name": "ChainOfThoughtAccordion", "group": "Components", "storyId": "solid-advanced-elements-chainofthoughtaccordion--docs" } ], "tokens": [] }, { "tag": "kai-chat", "className": "KaiChatElement", "displayName": "Chat", "props": [ { "name": "messages", "type": "{ id: string; role: \"user\" | \"assistant\"; content: string; reasoning?: undefined | { text: string; label?: undefined | string }; tools?: undefined | { type: string; state: \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"; input?: undefined | Record<string, unknown>; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string }[]; attachments?: undefined | { id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]; actions?: undefined | (\"copy\" | \"like\" | \"dislike\" | \"regenerate\" | \"edit\" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | \"like\" | \"dislike\" }[]", "optional": false, "scalar": false, "description": "The full message thread to render, newest last. Each entry carries its role, content, and optional reasoning/tools/attachments/actions. Set as a JS property (`el.messages = [...]`).", "typeName": "ChatMessage[]", "typeShape": "{ id: string; role: \"user\" | \"assistant\"; content: string; reasoning?: undefined | { text: string; label?: undefined | string }; tools?: undefined | { type: string; state: \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"; input?: undefined | Record<string, unknown>; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string }[]; attachments?: undefined | { id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]; actions?: undefined | (\"copy\" | \"like\" | \"dislike\" | \"regenerate\" | \"edit\" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | \"like\" | \"dislike\" }[]", "default": "[]", "typeImport": "ChatMessage", "displayType": "{ id: string; role: \"user\" | \"assistant\"; content: string; reasoning?: undefined | { text: string; label?: undefined | string }; tools?: undefined | { type: string; state: \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"; input?: undefined | Record<string, unknown>; output?: undefined | Record<string, unknown>; toolCallId?: undefined | string; errorText?: undefined | string }[]; attachments?: undefined | { id: string; type: \"file\" | \"source-document\"; filename?: undefined | string; mediaType?: undefined | string; url?: undefined | string; title?: undefined | string }[]; actions?: undefined | (\"copy\" | \"like\" | \"dislike\" | \"regenerate\" | \"edit\" | { id: string; label: string; icon?: undefined | string; tooltip?: undefined | string })[]; avatar?: undefined | { src?: undefined | string; fallback?: undefined | string; alt?: undefined | string }; feedback?: undefined | \"like\" | \"dislike\" }[]" }, { "name": "value", "type": "undefined | string | ({ type: \"text\"; text: string } | { type: \"entity\"; entity: { kind: string; id: string; label: string; icon?: undefined | string; promptText?: undefined | string; data?: undefined | Record<string, unknown> } })[]", "optional": true, "scalar": false, "description": "Value of the input. A **string** is controlled (the host owns the text and updates it on `kai-value-change`). A **ComposerDoc** is a one-time seed that pre-populates pills; the user then edits freely. Leave unset for uncontrolled.", "displayType": "undefined | string | ({ type: \"text\"; text: string } | { type: \"entity\"; entity: { kind: string; id: string; label: string; icon?: undefined | string; promptText?: undefined | string; data?: undefined | Record<string, unknown> } })[]" }, { "name": "placeholder", "type": "undefined | string", "optional": true, "scalar": true, "description": "Placeholder text shown in the empty input.", "default": "'Send a message...'", "displayType": "undefined | string" }, { "name": "loading", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "When true, shows the loading/streaming state and disables submit (use while awaiting the assistant's reply).", "default": "false", "displayType": "undefined | false | true" }, { "name": "suggestions", "type": "undefined | string[]", "optional": true, "scalar": false, "description": "Starter prompts shown above the input when the thread is empty. Clicking one follows `suggestionMode`. Set as a JS property.", "displayType": "undefined | string[]" }, { "name": "suggestionMode", "type": "undefined | \"submit\" | \"fill\"", "optional": true, "scalar": true, "description": "What clicking a suggestion does: `'submit'` (default) sends it immediately as if typed and submitted; `'fill'` just places it in the input.", "default": "'submit'", "displayType": "undefined | \"submit\" | \"fill\"" }, { "name": "persistSuggestions", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Keep suggestions visible after the conversation starts. By default suggestions are conversation starters and hide once `messages` is non-empty; set this to keep them always shown. Default false.", "default": "false", "displayType": "undefined | false | true" }, { "name": "proseSize", "type": "undefined | \"sm\" | \"lg\" | \"xs\" | \"base\"", "optional": true, "scalar": true, "description": "Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`). Defaults to `'sm'`.", "default": "'sm'", "displayType": "undefined | \"sm\" | \"lg\" | \"xs\" | \"base\"" }, { "name": "codeTheme", "type": "undefined | string", "optional": true, "scalar": true, "description": "Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`).", "default": "'github-dark-dimmed'", "displayType": "undefined | string" }, { "name": "codeHighlight", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Enable Shiki syntax highlighting in code blocks. Turn off to render plain `<pre>` blocks (lighter, no highlighter load). Default true.", "default": "true", "displayType": "undefined | false | true" }, { "name": "chatTitle", "type": "undefined | string", "optional": true, "scalar": true, "description": "Optional header title shown on the left of the header.", "displayType": "undefined | string" }, { "name": "models", "type": "undefined | { id: string; name: string; provider?: undefined | string; description?: undefined | string; group?: undefined | string }[]", "optional": true, "scalar": false, "description": "Optional model list. When set (>1 model) a ModelSwitcher is shown in the header and a `kai-model-change` event fires on selection.", "displayType": "undefined | { id: string; name: string; provider?: undefined | string; description?: undefined | string; group?: undefined | string }[]" }, { "name": "currentModel", "type": "undefined | string", "optional": true, "scalar": true, "description": "The currently selected model id (pairs with `models`).", "displayType": "undefined | string" }, { "name": "context", "type": "undefined | { usedTokens: number; maxTokens: number; inputTokens?: undefined | number; outputTokens?: undefined | number; estimatedCost?: undefined | number }", "optional": true, "scalar": false, "description": "Optional context-window token usage. When set, a Context token meter is shown in the header.", "displayType": "ContextData | undefined" }, { "name": "scrollButton", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Show the scroll-to-bottom button inside the scroll area. Default true.", "default": "true", "displayType": "undefined | false | true" }, { "name": "headerStart", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Whether the host has `slot=\"header-start\"` content (left of the title) — set by the `<kai-chat>` facade so a custom control forces the header open.", "displayType": "undefined | false | true" }, { "name": "headerEnd", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "Whether the host has `slot=\"header-end\"` content (right of the controls).", "displayType": "undefined | false | true" }, { "name": "headerFull", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "REPLACE — full custom header in place of the built-in title/model/context bar.", "displayType": "undefined | false | true" }, { "name": "sidebar", "type": "undefined | false | true", "optional": true, "scalar": true, "description": "INJECT — left sidebar column (e.g. a conversation list / your own nav).", "displayType": "undefined | false | true" }, { "name