@kitnai/chat 0.3.1 → 0.5.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 +35 -5
- package/dist/custom-elements.json +2969 -0
- package/dist/kitn-chat.es.js +52 -39
- package/dist/llms/llms-full.txt +718 -0
- package/dist/llms/llms.txt +104 -0
- package/dist/theme.tokens.css +137 -0
- package/frameworks/react/index.tsx +584 -0
- package/frameworks/react/runtime.tsx +94 -0
- package/llms-full.txt +718 -0
- package/llms.txt +104 -0
- package/package.json +53 -6
- package/src/components/attachments.tsx +4 -2
- package/src/components/chain-of-thought.tsx +1 -1
- package/src/components/chat-scope-picker.tsx +2 -2
- package/src/components/chat-thread.tsx +217 -0
- package/src/components/checkpoint.tsx +7 -3
- package/src/components/context.tsx +14 -18
- package/src/components/conversation-item.tsx +1 -1
- package/src/components/conversation-list.tsx +5 -4
- package/src/components/message-skills.tsx +1 -1
- package/src/components/message.tsx +1 -0
- package/src/components/model-switcher.tsx +3 -3
- package/src/components/prompt-input.tsx +20 -2
- package/src/components/reasoning.tsx +2 -2
- package/src/components/scroll-button.tsx +1 -0
- package/src/components/slash-command.tsx +17 -8
- package/src/components/source.tsx +2 -2
- package/src/components/thinking-bar.tsx +2 -2
- package/src/components/tool.tsx +17 -6
- package/src/components/voice-input.tsx +5 -1
- package/src/elements/attachments.tsx +132 -0
- package/src/elements/chain-of-thought.tsx +45 -0
- package/src/elements/chat-scope-picker.tsx +36 -0
- package/src/elements/chat-workspace.tsx +122 -0
- package/src/elements/chat.tsx +31 -228
- package/src/elements/checkpoint.tsx +43 -0
- package/src/elements/code-block.tsx +42 -0
- package/src/elements/compiled.css +1 -1
- package/src/elements/context-meter.tsx +71 -0
- package/src/elements/conversation-list.tsx +6 -0
- package/src/elements/default-input.tsx +22 -1
- package/src/elements/define.tsx +98 -12
- package/src/elements/element-types.d.ts +444 -0
- package/src/elements/empty.tsx +29 -0
- package/src/elements/feedback-bar.tsx +33 -0
- package/src/elements/file-upload.tsx +44 -0
- package/src/elements/image.tsx +32 -0
- package/src/elements/kitn-attachments.stories.tsx +181 -0
- package/src/elements/kitn-chain-of-thought.stories.tsx +75 -0
- package/src/elements/kitn-chat-scope-picker.stories.tsx +72 -0
- package/src/elements/kitn-chat-workspace.stories.tsx +195 -0
- package/src/elements/kitn-checkpoint.stories.tsx +71 -0
- package/src/elements/kitn-code-block.stories.tsx +82 -0
- package/src/elements/kitn-context-meter.stories.tsx +85 -0
- package/src/elements/kitn-empty.stories.tsx +110 -0
- package/src/elements/kitn-feedback-bar.stories.tsx +73 -0
- package/src/elements/kitn-file-upload.stories.tsx +81 -0
- package/src/elements/kitn-image.stories.tsx +70 -0
- package/src/elements/kitn-loader.stories.tsx +87 -0
- package/src/elements/kitn-markdown.stories.tsx +75 -0
- package/src/elements/kitn-message-skills.stories.tsx +74 -0
- package/src/elements/kitn-message.stories.tsx +105 -0
- package/src/elements/kitn-model-switcher.stories.tsx +80 -0
- package/src/elements/kitn-prompt-input.stories.tsx +74 -16
- package/src/elements/kitn-prompt-suggestions.stories.tsx +157 -0
- package/src/elements/kitn-reasoning.stories.tsx +76 -0
- package/src/elements/kitn-response-stream.stories.tsx +79 -0
- package/src/elements/kitn-source-list.stories.tsx +77 -0
- package/src/elements/kitn-source.stories.tsx +87 -0
- package/src/elements/kitn-text-shimmer.stories.tsx +63 -0
- package/src/elements/kitn-thinking-bar.stories.tsx +72 -0
- package/src/elements/kitn-tool.stories.tsx +88 -0
- package/src/elements/kitn-voice-input.stories.tsx +87 -0
- package/src/elements/loader.tsx +25 -0
- package/src/elements/markdown.tsx +38 -0
- package/src/elements/message-skills.tsx +22 -0
- package/src/elements/message.tsx +125 -0
- package/src/elements/model-switcher.tsx +35 -0
- package/src/elements/prompt-input.tsx +83 -7
- package/src/elements/prompt-suggestions.tsx +58 -0
- package/src/elements/reasoning.tsx +50 -0
- package/src/elements/register.ts +32 -0
- package/src/elements/response-stream.tsx +40 -0
- package/src/elements/source.tsx +67 -0
- package/src/elements/styles.css +14 -0
- package/src/elements/text-shimmer.tsx +28 -0
- package/src/elements/thinking-bar.tsx +34 -0
- package/src/elements/tool.tsx +23 -0
- package/src/elements/voice-input.tsx +41 -0
- package/src/index.ts +0 -1
- package/src/primitives/chat-config.tsx +3 -3
- package/src/stories/docs/Accessibility.mdx +119 -0
- package/src/stories/docs/ForAIAgents.mdx +93 -0
- package/src/stories/docs/GettingStarted.mdx +2 -2
- package/src/stories/docs/Installation.mdx +29 -2
- package/src/stories/docs/Integrations.mdx +417 -15
- package/src/stories/docs/Introduction.mdx +17 -8
- package/src/stories/docs/Theming.mdx +1 -1
- package/src/stories/pattern-centered-conversation.stories.tsx +93 -0
- package/src/stories/pattern-docked-widget.stories.tsx +93 -0
- package/src/stories/pattern-empty-state.stories.tsx +76 -0
- package/src/stories/typography.stories.tsx +78 -0
- package/src/ui/button.tsx +1 -1
- package/src/ui/collapsible.stories.tsx +70 -0
- package/src/ui/collapsible.tsx +119 -8
- package/src/ui/dropdown.stories.tsx +60 -0
- package/src/ui/dropdown.tsx +177 -12
- package/src/ui/hover-card.stories.tsx +78 -0
- package/src/ui/hover-card.tsx +147 -26
- package/src/ui/overlay.stories.tsx +115 -0
- package/src/ui/overlay.tsx +151 -0
- package/src/ui/scroll-area.stories.tsx +51 -0
- package/src/ui/textarea.stories.tsx +77 -0
- package/src/ui/textarea.tsx +1 -1
- package/src/ui/tooltip.stories.tsx +1 -1
- package/src/ui/tooltip.tsx +59 -13
- package/src/utils/cn.ts +19 -1
- package/theme.css +76 -43
- package/src/ui/dialog.tsx +0 -21
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Runtime for the generated React wrappers (react/index.tsx). Renders the custom
|
|
2
|
+
// element and bridges the React world to it: rich props are assigned as DOM
|
|
3
|
+
// *properties* (via a ref, so arrays/objects pass through unstringified), and
|
|
4
|
+
// `on<Event>` handlers are wired as `addEventListener` for the element's
|
|
5
|
+
// CustomEvents. Layout props (className/style/id) pass straight through.
|
|
6
|
+
import {
|
|
7
|
+
createElement,
|
|
8
|
+
forwardRef,
|
|
9
|
+
useImperativeHandle,
|
|
10
|
+
useLayoutEffect,
|
|
11
|
+
useRef,
|
|
12
|
+
type CSSProperties,
|
|
13
|
+
type ForwardRefExoticComponent,
|
|
14
|
+
type PropsWithoutRef,
|
|
15
|
+
type ReactNode,
|
|
16
|
+
type RefAttributes,
|
|
17
|
+
} from 'react';
|
|
18
|
+
|
|
19
|
+
export interface KitnBaseProps {
|
|
20
|
+
/** Color mode (`auto` follows prefers-color-scheme). */
|
|
21
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
22
|
+
className?: string;
|
|
23
|
+
style?: CSSProperties;
|
|
24
|
+
id?: string;
|
|
25
|
+
/** Light-DOM children passed through to the element (slots). */
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createKitnComponent<P extends KitnBaseProps>(
|
|
30
|
+
tagName: string,
|
|
31
|
+
/** DOM-property names to assign from props (incl. `theme`). */
|
|
32
|
+
propNames: readonly string[],
|
|
33
|
+
/** Map of React handler prop → DOM event name, e.g. `{ onMessageaction: 'messageaction' }`. */
|
|
34
|
+
eventMap: Record<string, string>,
|
|
35
|
+
): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<HTMLElement>> {
|
|
36
|
+
const eventEntries = Object.entries(eventMap);
|
|
37
|
+
|
|
38
|
+
const Component = forwardRef<HTMLElement, P>((props, ref) => {
|
|
39
|
+
const elRef = useRef<HTMLElement | null>(null);
|
|
40
|
+
useImperativeHandle(ref, () => elRef.current as HTMLElement, []);
|
|
41
|
+
const p = props as Record<string, unknown>;
|
|
42
|
+
|
|
43
|
+
// Hold the latest handlers in a ref so the registered listeners always call
|
|
44
|
+
// the current handler (no stale closures) without re-binding on every render.
|
|
45
|
+
const handlersRef = useRef<Record<string, unknown>>({});
|
|
46
|
+
for (const reactName of Object.keys(eventMap)) handlersRef.current[reactName] = p[reactName];
|
|
47
|
+
|
|
48
|
+
// Assign rich props as DOM properties every render (idempotent). Arrays and
|
|
49
|
+
// objects pass through unstringified; booleans become real boolean
|
|
50
|
+
// properties so the element's `flag()` reads them. Updated props re-assign
|
|
51
|
+
// because this effect runs after every render.
|
|
52
|
+
useLayoutEffect(() => {
|
|
53
|
+
const el = elRef.current;
|
|
54
|
+
if (!el) return;
|
|
55
|
+
for (const name of propNames) {
|
|
56
|
+
if (name in p && p[name] !== undefined) (el as unknown as Record<string, unknown>)[name] = p[name];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Wire CustomEvent listeners ONCE per element. Each stable listener reads the
|
|
61
|
+
// latest handler from handlersRef, so changing a handler's identity across
|
|
62
|
+
// renders takes effect without add/remove churn, and listeners are removed on
|
|
63
|
+
// unmount (no leaks).
|
|
64
|
+
useLayoutEffect(() => {
|
|
65
|
+
const el = elRef.current;
|
|
66
|
+
if (!el) return;
|
|
67
|
+
const added: Array<[string, EventListener]> = [];
|
|
68
|
+
for (const [reactName, domName] of eventEntries) {
|
|
69
|
+
const fn: EventListener = (e) => {
|
|
70
|
+
const handler = handlersRef.current[reactName];
|
|
71
|
+
if (typeof handler === 'function') (handler as (e: Event) => void)(e);
|
|
72
|
+
};
|
|
73
|
+
el.addEventListener(domName, fn);
|
|
74
|
+
added.push([domName, fn]);
|
|
75
|
+
}
|
|
76
|
+
return () => added.forEach(([n, fn]) => el.removeEventListener(n, fn));
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
return createElement(
|
|
80
|
+
tagName,
|
|
81
|
+
{
|
|
82
|
+
ref: elRef,
|
|
83
|
+
className: p.className as string | undefined,
|
|
84
|
+
style: p.style as CSSProperties | undefined,
|
|
85
|
+
id: p.id as string | undefined,
|
|
86
|
+
},
|
|
87
|
+
// Light-DOM children pass straight through to the element (slots).
|
|
88
|
+
(p.children ?? null) as never,
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
Component.displayName = tagName;
|
|
93
|
+
return Component as ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<HTMLElement>>;
|
|
94
|
+
}
|