@kitn.ai/ui 0.18.1 → 0.19.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/dist/components/thread.d.ts +54 -0
- package/dist/custom-elements.json +195 -0
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/chunks/{Icon-C2LTALdM.js → Icon-11SRdjJ4.js} +1 -1
- package/dist/elements/chunks/action-icons-CtRg17uX.js +1 -0
- package/dist/elements/chunks/arrow-left-CifsGq8x.js +1 -0
- package/dist/elements/chunks/{attachments-DLJcWCDV.js → attachments-CBqQRh60.js} +1 -1
- package/dist/elements/chunks/{badge-BTNZTODL.js → badge-CxklEXQm.js} +1 -1
- package/dist/elements/chunks/{button-DBDZebGr.js → button-BD7lUvVB.js} +1 -1
- package/dist/elements/chunks/{card-YfCyI4fH.js → card-B-PRGXdj.js} +1 -1
- package/dist/elements/chunks/chat-thread-DIZbRIKG.js +1 -0
- package/dist/elements/chunks/check-CUKS495w.js +1 -0
- package/dist/elements/chunks/chevron-down-AELmYT1j.js +1 -0
- package/dist/elements/chunks/chevron-right-C8g26oKh.js +1 -0
- package/dist/elements/chunks/circle-DGcI8Cft.js +1 -0
- package/dist/elements/chunks/circle-check-DuU0IcBQ.js +1 -0
- package/dist/elements/chunks/{circle-x-pDtzlghQ.js → circle-x-mtjCO_Ok.js} +1 -1
- package/dist/elements/chunks/{code-block-DZ6mz6vs.js → code-block-BeWVttmU.js} +1 -1
- package/dist/elements/chunks/{collapsible-CWUAShMC.js → collapsible-DGjADCN6.js} +1 -1
- package/dist/elements/chunks/{composer-BZyPU6gD.js → composer-CavJww3d.js} +7 -3
- package/dist/elements/chunks/{context-Cx6eQA_G.js → context-CnlsNJSJ.js} +1 -1
- package/dist/elements/chunks/{conversation-list-C4xTQSpT.js → conversation-list-5O_KdI_I.js} +1 -1
- package/dist/elements/chunks/{default-input-BZcwyKcP.js → default-input-CB46cJJ1.js} +1 -1
- package/dist/elements/chunks/{define-CNSKFZCd.js → define-DfTe4zwZ.js} +1 -1
- package/dist/elements/chunks/{disclosure-BcBs--Jf.js → disclosure-BtFK3a-M.js} +1 -1
- package/dist/elements/chunks/{download-BDQwcFav.js → download-qJv1dS3M.js} +1 -1
- package/dist/elements/chunks/{dropdown-wgs8xCJZ.js → dropdown-UhtAueYR.js} +1 -1
- package/dist/elements/chunks/{ellipsis-CUiEJ6R1.js → ellipsis-B1sOOqiJ.js} +1 -1
- package/dist/elements/chunks/{external-link-DJUmC7g2.js → external-link-DToP_VKE.js} +1 -1
- package/dist/elements/chunks/{file-text-DOYfYvrh.js → file-text-BwUs_Pj4.js} +1 -1
- package/dist/elements/chunks/{file-tree-DQzNQrbr.js → file-tree-C6RhmSnX.js} +1 -1
- package/dist/elements/chunks/{folder-DBDUBANz.js → folder-H_Xp0GYP.js} +1 -1
- package/dist/elements/chunks/hover-card-Dn3yrk1l.js +1 -0
- package/dist/elements/chunks/icon-BrxJQXzC.js +1 -0
- package/dist/elements/chunks/{info-DBQl-m6e.js → info-11eT2q5H.js} +1 -1
- package/dist/elements/chunks/{input-DZD67EvW.js → input-B9oZKDfb.js} +1 -1
- package/dist/elements/chunks/{kbd-DbyVrlnU.js → kbd-D2fx3rWh.js} +1 -1
- package/dist/elements/chunks/{link-vko7AttA.js → link-B-RNYWNw.js} +1 -1
- package/dist/elements/chunks/{loader-Cg6rO8tQ.js → loader-BJh_aRlp.js} +1 -1
- package/dist/elements/chunks/{markdown-n3Xbj3PR.js → markdown-BIpjrDFv.js} +1 -1
- package/dist/elements/chunks/{message-CgKytiSB.js → message-CPfqj8Gi.js} +1 -1
- package/dist/elements/chunks/{message-feedback-Ds3-US0e.js → message-feedback-8uj0aVYh.js} +1 -1
- package/dist/elements/chunks/message-square-CCSQ4M9g.js +1 -0
- package/dist/elements/chunks/{minimize-2-3kCdE0q3.js → minimize-2-C9qkiTJg.js} +1 -1
- package/dist/elements/chunks/{model-switcher-BMtXGwLU.js → model-switcher-DRrMcRXH.js} +1 -1
- package/dist/elements/chunks/{overlay-B1-MBI6h.js → overlay-C8_FUL8q.js} +1 -1
- package/dist/elements/chunks/{paperclip-DDEfmkHc.js → paperclip-MA9hxLhW.js} +1 -1
- package/dist/elements/chunks/{progress-bar-Dwbiyv3s.js → progress-bar-y5G6HDjg.js} +1 -1
- package/dist/elements/chunks/{prompt-suggestion-9lvgFcEa.js → prompt-suggestion-LalWvCJy.js} +1 -1
- package/dist/elements/chunks/reasoning-CW3SDdb4.js +1 -0
- package/dist/elements/chunks/resizable-xhYF5lCQ.js +1 -0
- package/dist/elements/chunks/{rotate-cw-jpisOdOV.js → rotate-cw-2ndEXjgS.js} +1 -1
- package/dist/elements/chunks/{scroll-area-g5Ze3K6f.js → scroll-area-BzOPDXrZ.js} +1 -1
- package/dist/elements/chunks/scroll-button-B1x4cYqM.js +1 -0
- package/dist/elements/chunks/{separator-Bmjc5XyX.js → separator-CPvL5Xdl.js} +1 -1
- package/dist/elements/chunks/{settings-group-9imY3kRA.js → settings-group-BiIym17O.js} +1 -1
- package/dist/elements/chunks/{settings-Cz1bMJP9.js → settings-hmzIuNXD.js} +1 -1
- package/dist/elements/chunks/{share-BdenF0wQ.js → share-BbziTAzn.js} +1 -1
- package/dist/elements/chunks/skeleton-Bxhs1thL.js +1 -0
- package/dist/elements/chunks/{slots-DkZ-Cmha.js → slots--V19HwUb.js} +1 -1
- package/dist/elements/chunks/{star-DY6z1UUH.js → star-BHL3Va5p.js} +1 -1
- package/dist/elements/chunks/{store-th4VyJXM.js → store-tpnnWlxY.js} +1 -1
- package/dist/elements/chunks/{text-shimmer-CEi-tlXr.js → text-shimmer-1DCKivKx.js} +1 -1
- package/dist/elements/chunks/textarea-Czaowo9F.js +1 -0
- package/dist/elements/chunks/{thumbs-up-BR33KLfA.js → thumbs-up-CdLqA13R.js} +1 -1
- package/dist/elements/chunks/{toast-store-BEMda0fv.js → toast-store-BvBquUFA.js} +1 -1
- package/dist/elements/chunks/{tool-TMued3WO.js → tool-4P_ne8Go.js} +1 -1
- package/dist/elements/chunks/{tooltip-Cft_Rxiw.js → tooltip-CBeFqJKk.js} +1 -1
- package/dist/elements/chunks/{triangle-alert-B07fX3Q8.js → triangle-alert-BllqxXq8.js} +1 -1
- package/dist/elements/chunks/{use-card-resolution-M36zVciB.js → use-card-resolution-73xiddIW.js} +1 -1
- package/dist/elements/chunks/{video-MKp3LmNT.js → video-O9rA6k7S.js} +1 -1
- package/dist/elements/chunks/x-DeS3rQhx.js +1 -0
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +1 -1
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slots.d.ts +3 -0
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.d.ts +1 -0
- package/dist/elements/thread.js +1 -0
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +24 -0
- package/dist/index.js +3393 -3311
- package/dist/kai.es.js +1 -1
- package/dist/llms/llms-full.txt +34 -4
- package/dist/llms/llms.txt +3 -3
- package/dist/react/index.d.ts +64 -0
- package/dist/react/use-voice-input.d.ts +15 -0
- package/dist/react.js +263 -240
- package/dist/register-impl-CaaHJcea.js +145 -0
- package/dist/ui/resizable.d.ts +9 -3
- package/frameworks/react/index.tsx +32 -1
- package/frameworks/react/use-voice-input.tsx +59 -0
- package/llms-full.txt +34 -4
- package/llms.txt +3 -3
- package/package.json +27 -5
- package/src/components/component-meta.json +30 -28
- package/src/components/composer.tsx +5 -0
- package/src/components/thread.tsx +177 -0
- package/src/elements/chat-workspace.tsx +1 -1
- package/src/elements/compiled.css +1 -1
- package/src/elements/element-manifest.json +4 -0
- package/src/elements/element-meta.json +117 -0
- package/src/elements/element-types.d.ts +24 -0
- package/src/elements/icon-names.json +2 -0
- package/src/elements/menu.tsx +7 -4
- package/src/elements/register-impl.ts +2 -0
- package/src/elements/resizable.tsx +78 -2
- package/src/elements/search.tsx +1 -1
- package/src/elements/slots.ts +7 -0
- package/src/elements/thread.tsx +105 -0
- package/src/ui/action-icons.ts +2 -1
- package/src/ui/command.tsx +5 -1
- package/src/ui/icon.tsx +4 -0
- package/src/ui/overlay.tsx +8 -1
- package/src/ui/resizable.tsx +47 -9
- package/dist/elements/chunks/action-icons-Dtl8Ox5D.js +0 -1
- package/dist/elements/chunks/arrow-left-GbBceGBE.js +0 -1
- package/dist/elements/chunks/chat-thread-Dz2qbzvI.js +0 -1
- package/dist/elements/chunks/check-fhmRksq_.js +0 -1
- package/dist/elements/chunks/chevron-down-DcRg1aRU.js +0 -1
- package/dist/elements/chunks/chevron-right-ChzBcNJ-.js +0 -1
- package/dist/elements/chunks/circle-B4fTe9v6.js +0 -1
- package/dist/elements/chunks/circle-check-CJV-3Rem.js +0 -1
- package/dist/elements/chunks/hover-card-BQGdGAQ3.js +0 -1
- package/dist/elements/chunks/icon-CAyRqVrg.js +0 -1
- package/dist/elements/chunks/message-square-MmRkvc-M.js +0 -1
- package/dist/elements/chunks/reasoning-DzHWsdAJ.js +0 -1
- package/dist/elements/chunks/resizable-Bq_eHxUm.js +0 -1
- package/dist/elements/chunks/skeleton-Pjc5jiaY.js +0 -1
- package/dist/elements/chunks/textarea-CboigarR.js +0 -1
- package/dist/elements/chunks/x-Ckwicf6g.js +0 -1
- package/dist/register-impl-cKscku5m.js +0 -141
package/dist/ui/resizable.d.ts
CHANGED
|
@@ -52,7 +52,13 @@ export interface ResizablePanelProps extends JSX.HTMLAttributes<HTMLDivElement>
|
|
|
52
52
|
}
|
|
53
53
|
declare function ResizablePanel(props: ResizablePanelProps): JSX.Element;
|
|
54
54
|
export interface ResizableHandleProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
|
55
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Divider affordance drawn inside the 8px grab zone:
|
|
57
|
+
* - `line` (default) — a 1px hairline, transparent at rest, tinting on hover/drag.
|
|
58
|
+
* - `grip` — a dotted grip handle.
|
|
59
|
+
* - `none` — no visible divider (invisible hit-area only).
|
|
60
|
+
*/
|
|
61
|
+
handle?: 'line' | 'grip' | 'none';
|
|
56
62
|
onPanelResize?: (delta: number) => void;
|
|
57
63
|
/** Keyboard nudge step in pixels (default 16). Home/End jump to min/max. */
|
|
58
64
|
keyboardStep?: number;
|
|
@@ -67,8 +73,8 @@ export interface ResizableProps {
|
|
|
67
73
|
orientation?: Orientation;
|
|
68
74
|
/** Fired on drag-end / keyboard resize / visibility change with the current panel sizes (percent). */
|
|
69
75
|
onChange?: (sizes: number[]) => void;
|
|
70
|
-
/**
|
|
71
|
-
|
|
76
|
+
/** Divider affordance on each interactive handle: `line` (default), `grip`, or `none`. */
|
|
77
|
+
handle?: 'line' | 'grip' | 'none';
|
|
72
78
|
class?: string;
|
|
73
79
|
/** Which panel index is maximized (null = none). Hides the others. */
|
|
74
80
|
maximizedIndex?: number | null;
|
|
@@ -11,6 +11,7 @@ import { createWebComponent, registerAll, type WebComponentProps } from './runti
|
|
|
11
11
|
export { registerAll };
|
|
12
12
|
export { useKaiChat } from './use-kai-chat';
|
|
13
13
|
export type { UseKaiChatOptions, KaiChatController, ChatMessage } from './use-kai-chat';
|
|
14
|
+
export { useVoiceInput } from './use-voice-input';
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
export interface AgentCardProps extends WebComponentProps {
|
|
@@ -1250,6 +1251,8 @@ export interface ResizableProps extends WebComponentProps {
|
|
|
1250
1251
|
orientation?: "vertical" | "horizontal";
|
|
1251
1252
|
/** Which item index is maximized (null = none). Declarative source of truth. */
|
|
1252
1253
|
maximizedIndex?: null | number;
|
|
1254
|
+
/** Divider affordance drawn inside each draggable handle's 8px grab zone: - `line` (default) — a 1px hairline, transparent at rest, tinting on hover/drag. - `grip` — a dotted grip handle. - `none` — no visible divider, just the invisible hit-area. The full grab zone and keyboard/ARIA behavior are identical for all three. */
|
|
1255
|
+
handle?: "none" | "line" | "grip";
|
|
1253
1256
|
/** Fired on drag-end / keyboard resize / visibility change. `detail.sizes` = panel sizes in percent. */
|
|
1254
1257
|
onChange?: (event: CustomEvent<{ sizes: number[] }>) => void;
|
|
1255
1258
|
/** Observe layout maximize state. */
|
|
@@ -1258,7 +1261,7 @@ export interface ResizableProps extends WebComponentProps {
|
|
|
1258
1261
|
|
|
1259
1262
|
export const Resizable = /*#__PURE__*/ createWebComponent<ResizableProps>(
|
|
1260
1263
|
'kai-resizable',
|
|
1261
|
-
["theme","orientation","maximizedIndex"],
|
|
1264
|
+
["theme","orientation","maximizedIndex","handle"],
|
|
1262
1265
|
{ onChange: 'kai-change', onMaximizeChange: 'kai-maximize-change' },
|
|
1263
1266
|
() => import('@kitn.ai/ui/elements/resizable'),
|
|
1264
1267
|
);
|
|
@@ -1693,6 +1696,34 @@ export const ThinkingBar = /*#__PURE__*/ createWebComponent<ThinkingBarProps>(
|
|
|
1693
1696
|
() => import('@kitn.ai/ui/elements/thinking-bar'),
|
|
1694
1697
|
);
|
|
1695
1698
|
|
|
1699
|
+
export interface ThreadProps extends WebComponentProps {
|
|
1700
|
+
/** The full message thread to render, newest last. Each entry carries its role, content, and optional reasoning/tools/attachments/actions/avatar. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). */
|
|
1701
|
+
messages?: { id: string; role: "user" | "assistant"; content: string; reasoning?: { text: string; label?: string }; tools?: { type: string; state: "input-streaming" | "input-available" | "output-available" | "output-error"; input?: Record<string, unknown>; output?: Record<string, unknown>; toolCallId?: string; errorText?: string }[]; attachments?: { id: string; type: "file" | "source-document"; filename?: string; mediaType?: string; url?: string; title?: string }[]; actions?: ("copy" | "like" | "dislike" | "regenerate" | "edit" | { id: string; label: string; icon?: string; tooltip?: string })[]; avatar?: { src?: string; fallback?: string; alt?: string }; feedback?: "like" | "dislike" }[];
|
|
1702
|
+
/** Show a typing indicator on the pending assistant turn — set while awaiting the assistant's reply. */
|
|
1703
|
+
loading?: boolean;
|
|
1704
|
+
/** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`). Defaults to `'sm'`. */
|
|
1705
|
+
proseSize?: "sm" | "lg" | "xs" | "base";
|
|
1706
|
+
/** Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`). */
|
|
1707
|
+
codeTheme?: string;
|
|
1708
|
+
/** Enable Shiki syntax highlighting in code blocks. Turn off to render plain `<pre>` blocks (lighter, no highlighter load). Default true. */
|
|
1709
|
+
codeHighlight?: boolean;
|
|
1710
|
+
/** Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). */
|
|
1711
|
+
actionsReveal?: "always" | "hover";
|
|
1712
|
+
/** Show the scroll-to-bottom button inside the scroll area. Default true. */
|
|
1713
|
+
scrollButton?: boolean;
|
|
1714
|
+
/** Extra classes applied to the thread's inner root. */
|
|
1715
|
+
class?: string;
|
|
1716
|
+
/** A message's action button was clicked. `action` is the built-in name (`copy` / `like` / `dislike` / `regenerate` / `edit`) or a custom id. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. */
|
|
1717
|
+
onMessageAction?: (event: CustomEvent<{ messageId: string; action: string; state?: undefined | "on" | "off" }>) => void;
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
export const Thread = /*#__PURE__*/ createWebComponent<ThreadProps>(
|
|
1721
|
+
'kai-thread',
|
|
1722
|
+
["theme","messages","loading","proseSize","codeTheme","codeHighlight","actionsReveal","scrollButton","class"],
|
|
1723
|
+
{ onMessageAction: 'kai-message-action' },
|
|
1724
|
+
() => import('@kitn.ai/ui/elements/thread'),
|
|
1725
|
+
);
|
|
1726
|
+
|
|
1696
1727
|
export interface ToastRegionProps extends WebComponentProps {
|
|
1697
1728
|
/** The toasts to render. Newest is shown on top. Set as a JS property (array); pass a new array reference to update. */
|
|
1698
1729
|
toasts: { id: string; message: string; variant?: undefined | "error" | "info" | "success" | "warning" | "neutral"; appearance?: undefined | "pill" | "card"; inverse?: undefined | boolean; description?: undefined | string; action?: undefined | { label: string; onAction: () => void | false }; duration?: undefined | number; dismissible?: undefined | boolean; target?: undefined | HTMLElement }[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/** Minimal shape of a Web Speech recognition result event — enough to read the
|
|
4
|
+
* first transcript. The full SpeechRecognition API isn't in TS's lib.dom yet. */
|
|
5
|
+
interface SpeechResultEvent {
|
|
6
|
+
results: ArrayLike<ArrayLike<{ transcript: string }>>;
|
|
7
|
+
}
|
|
8
|
+
interface SpeechRecognitionLike {
|
|
9
|
+
lang: string;
|
|
10
|
+
interimResults: boolean;
|
|
11
|
+
onresult: ((event: SpeechResultEvent) => void) | null;
|
|
12
|
+
start(): void;
|
|
13
|
+
}
|
|
14
|
+
type SpeechRecognitionCtor = new () => SpeechRecognitionLike;
|
|
15
|
+
|
|
16
|
+
/** Resolve the Chromium (`webkitSpeechRecognition`) or standard constructor, if any. */
|
|
17
|
+
function getSpeechRecognition(): SpeechRecognitionCtor | undefined {
|
|
18
|
+
if (typeof window === 'undefined') return undefined;
|
|
19
|
+
const w = window as unknown as {
|
|
20
|
+
SpeechRecognition?: SpeechRecognitionCtor;
|
|
21
|
+
webkitSpeechRecognition?: SpeechRecognitionCtor;
|
|
22
|
+
};
|
|
23
|
+
return w.SpeechRecognition ?? w.webkitSpeechRecognition;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Web Speech mic → one-shot transcript. Chromium-only (`webkitSpeechRecognition`);
|
|
28
|
+
* `supported` is false elsewhere so the caller can degrade gracefully. This hook is
|
|
29
|
+
* deliberately ONLY about speech recognition: it hands the raw transcript to
|
|
30
|
+
* `onTranscript` and lets the caller decide what to do with it (e.g. a composer mic
|
|
31
|
+
* button appends it to the live text). No composer or DOM knowledge.
|
|
32
|
+
*
|
|
33
|
+
* @param onTranscript called with the final recognized transcript.
|
|
34
|
+
* @returns `supported` (Chromium-only availability) and a referentially stable,
|
|
35
|
+
* one-shot `start` (a no-op when unsupported).
|
|
36
|
+
*/
|
|
37
|
+
export function useVoiceInput(onTranscript: (transcript: string) => void): {
|
|
38
|
+
supported: boolean;
|
|
39
|
+
start: () => void;
|
|
40
|
+
} {
|
|
41
|
+
// Latest-callback ref: keeps `start` stable while always calling the current
|
|
42
|
+
// `onTranscript` (no stale closure, no re-created handler each render).
|
|
43
|
+
const cbRef = useRef(onTranscript);
|
|
44
|
+
cbRef.current = onTranscript;
|
|
45
|
+
|
|
46
|
+
const supported = getSpeechRecognition() !== undefined;
|
|
47
|
+
|
|
48
|
+
const start = useCallback(() => {
|
|
49
|
+
const Recognition = getSpeechRecognition();
|
|
50
|
+
if (!Recognition) return;
|
|
51
|
+
const rec = new Recognition();
|
|
52
|
+
rec.lang = 'en-US';
|
|
53
|
+
rec.interimResults = false;
|
|
54
|
+
rec.onresult = (event) => cbRef.current(event.results[0][0].transcript);
|
|
55
|
+
rec.start();
|
|
56
|
+
}, []);
|
|
57
|
+
|
|
58
|
+
return { supported, start };
|
|
59
|
+
}
|
package/llms-full.txt
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @kitn.ai/ui
|
|
5
5
|
|
|
6
|
-
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML.
|
|
6
|
+
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 79 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -37,7 +37,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
|
|
|
37
37
|
- `<kai-prompt-input>` — standalone composer with send button.
|
|
38
38
|
|
|
39
39
|
**Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
|
|
40
|
-
All
|
|
40
|
+
All 79 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
|
|
41
41
|
|
|
42
42
|
## Key rules for the web components
|
|
43
43
|
|
|
@@ -99,7 +99,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
|
|
|
99
99
|
|
|
100
100
|
## Docs
|
|
101
101
|
|
|
102
|
-
- Full element reference (all
|
|
102
|
+
- Full element reference (all 79 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
|
|
103
103
|
- Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
|
|
104
104
|
- Working examples: https://github.com/kitn-ai/ui/tree/main/examples
|
|
105
105
|
- Storybook: https://storybook.kitn.dev
|
|
@@ -173,7 +173,7 @@ The same rule applies to every array/object property (`models`, `context`, `sugg
|
|
|
173
173
|
|
|
174
174
|
---
|
|
175
175
|
|
|
176
|
-
## Element reference (
|
|
176
|
+
## Element reference (79 elements, generated from custom-elements.json)
|
|
177
177
|
|
|
178
178
|
Every element also accepts the `theme` attribute. Array/object properties are marked with a `—` attribute: they must be set as JS properties.
|
|
179
179
|
|
|
@@ -1487,6 +1487,7 @@ _No events._
|
|
|
1487
1487
|
|---|---|---|---|
|
|
1488
1488
|
| `orientation` | `orientation` | `undefined \| "vertical" \| "horizontal"` | Layout axis: `horizontal` (row, default) or `vertical` (column). |
|
|
1489
1489
|
| `maximizedIndex` | — | `undefined \| null \| number` | Which item index is maximized (null = none). Declarative source of truth. |
|
|
1490
|
+
| `handle` | `handle` | `undefined \| "none" \| "line" \| "grip"` | Divider affordance drawn inside each draggable handle's 8px grab zone: - `line` (default) — a 1px hairline, transparent at rest, tinting on hover/drag. - `grip` — a dotted grip handle. - `none` — no visible divider, just the invisible hit-area. The full grab zone and keyboard/ARIA behavior are identical for all three. |
|
|
1490
1491
|
|
|
1491
1492
|
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
1492
1493
|
|
|
@@ -1963,6 +1964,35 @@ _No events._
|
|
|
1963
1964
|
|
|
1964
1965
|
---
|
|
1965
1966
|
|
|
1967
|
+
### `kai-thread` / `Thread`
|
|
1968
|
+
|
|
1969
|
+
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
|
1970
|
+
|
|
1971
|
+
| Property | Attribute | Type | Description |
|
|
1972
|
+
|---|---|---|---|
|
|
1973
|
+
| `messages` | — | `undefined \| { 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" }[]` | The full message thread to render, newest last. Each entry carries its role, content, and optional reasoning/tools/attachments/actions/avatar. Set as a JS property (`el.messages = [...]`); a NEW array reference per streaming chunk re-renders (mutating in place does not). |
|
|
1974
|
+
| `loading` | `loading` | `undefined \| false \| true` | Show a typing indicator on the pending assistant turn — set while awaiting the assistant's reply. |
|
|
1975
|
+
| `proseSize` | `prose-size` | `undefined \| "sm" \| "lg" \| "xs" \| "base"` | Body/prose font scale for rendered markdown (`'xs' \| 'sm' \| 'base' \| 'lg'`). Defaults to `'sm'`. |
|
|
1976
|
+
| `codeTheme` | `code-theme` | `undefined \| string` | Shiki theme name for syntax-highlighted code blocks (e.g. `'github-dark-dimmed'`). |
|
|
1977
|
+
| `codeHighlight` | `code-highlight` | `undefined \| false \| true` | Enable Shiki syntax highlighting in code blocks. Turn off to render plain `<pre>` blocks (lighter, no highlighter load). Default true. |
|
|
1978
|
+
| `actionsReveal` | `actions-reveal` | `undefined \| "always" \| "hover"` | Whether each message's action bar is always visible (`'always'`, default) or only revealed on hover of that message row (`'hover'`). |
|
|
1979
|
+
| `scrollButton` | `scroll-button` | `undefined \| false \| true` | Show the scroll-to-bottom button inside the scroll area. Default true. |
|
|
1980
|
+
| `class` | `class` | `undefined \| string` | Extra classes applied to the thread's inner root. |
|
|
1981
|
+
|
|
1982
|
+
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
1983
|
+
|
|
1984
|
+
| Event | `detail` type | Description |
|
|
1985
|
+
|---|---|---|
|
|
1986
|
+
| `kai-message-action` | `CustomEvent<{ messageId: string; action: string; state?: undefined \| "on" \| "off" }>` | A message's action button was clicked. `action` is the built-in name (`copy` / `like` / `dislike` / `regenerate` / `edit`) or a custom id. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. |
|
|
1987
|
+
|
|
1988
|
+
**Slots** (project your own markup via `slot="name"` on a light-DOM child):
|
|
1989
|
+
|
|
1990
|
+
| Slot | Mode | Description |
|
|
1991
|
+
|---|---|---|
|
|
1992
|
+
| `empty` | replace | Custom zero-state rendered in the message area while the thread is empty; replaces the built-in default. |
|
|
1993
|
+
|
|
1994
|
+
---
|
|
1995
|
+
|
|
1966
1996
|
### `kai-toast-region` / `ToastRegion`
|
|
1967
1997
|
|
|
1968
1998
|
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
|
|
2
2
|
# @kitn.ai/ui
|
|
3
3
|
|
|
4
|
-
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML.
|
|
4
|
+
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 79 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -35,7 +35,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
|
|
|
35
35
|
- `<kai-prompt-input>` — standalone composer with send button.
|
|
36
36
|
|
|
37
37
|
**Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
|
|
38
|
-
All
|
|
38
|
+
All 79 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
|
|
39
39
|
|
|
40
40
|
## Key rules for the web components
|
|
41
41
|
|
|
@@ -97,7 +97,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
|
|
|
97
97
|
|
|
98
98
|
## Docs
|
|
99
99
|
|
|
100
|
-
- Full element reference (all
|
|
100
|
+
- Full element reference (all 79 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
|
|
101
101
|
- Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
|
|
102
102
|
- Working examples: https://github.com/kitn-ai/ui/tree/main/examples
|
|
103
103
|
- Storybook: https://storybook.kitn.dev
|
package/package.json
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitn.ai/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"nx": {
|
|
5
|
-
"name": "ui"
|
|
5
|
+
"name": "ui",
|
|
6
|
+
"targets": {
|
|
7
|
+
"build-storybook": {
|
|
8
|
+
"dependsOn": [
|
|
9
|
+
"build"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"dev": {
|
|
13
|
+
"dependsOn": [
|
|
14
|
+
"build"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"test:storybook": {
|
|
18
|
+
"dependsOn": [
|
|
19
|
+
"build"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"test:storybook:ci": {
|
|
23
|
+
"dependsOn": [
|
|
24
|
+
"build"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
6
28
|
},
|
|
7
29
|
"type": "module",
|
|
8
30
|
"sideEffects": [
|
|
@@ -112,14 +134,14 @@
|
|
|
112
134
|
"test:storybook:ci": "node scripts/run-storybook-tests.mjs",
|
|
113
135
|
"test:watch": "vitest",
|
|
114
136
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.react.json && tsc --noEmit -p tsconfig.react.test.json && tsc --noEmit -p tsconfig.mcp.json",
|
|
115
|
-
"examples": "echo 'Serving repo root on http://localhost:8000 — open http://localhost:8000/examples/composable/index.html' && python3 -m http.server 8000",
|
|
137
|
+
"examples": "echo 'Serving repo root on http://localhost:8000 — open http://localhost:8000/examples/demos/composable/index.html' && python3 -m http.server 8000",
|
|
116
138
|
"dev": "npm run build:css && storybook dev -p 6006",
|
|
117
139
|
"storybook": "npm run build:css && storybook dev -p 6006",
|
|
118
140
|
"build-storybook": "npm run build:css && storybook build",
|
|
119
141
|
"build:css": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --minify",
|
|
120
142
|
"build:css:watch": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --watch",
|
|
121
|
-
"dev:provider": "vite ../../examples/remote-provider --port 6007 --strictPort",
|
|
122
|
-
"dev:host": "vite ../../examples/remote-host --port 6006 --strictPort",
|
|
143
|
+
"dev:provider": "vite ../../examples/internal/remote-provider --port 6007 --strictPort",
|
|
144
|
+
"dev:host": "vite ../../examples/internal/remote-host --port 6006 --strictPort",
|
|
123
145
|
"test:e2e": "playwright test",
|
|
124
146
|
"test:composer-ivp": "playwright test --config playwright.composer.config.ts",
|
|
125
147
|
"test:slots-ivp": "playwright test --config playwright.slots.config.ts",
|