@kitn.ai/ui 0.14.1 → 0.15.1

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.
Files changed (179) hide show
  1. package/dist/kitn-chat.es.js +1 -1
  2. package/package.json +6 -1
  3. package/src/components/component-meta.json +10 -10
  4. package/src/elements/compiled.css +1 -1
  5. package/src/remote/host-embed.ts +1 -1
  6. package/src/components/artifact.stories.tsx +0 -138
  7. package/src/components/attachments.stories.tsx +0 -303
  8. package/src/components/attachments.test.tsx +0 -64
  9. package/src/components/chain-of-thought.stories.tsx +0 -211
  10. package/src/components/chat-container.stories.tsx +0 -187
  11. package/src/components/chat-thread.test.tsx +0 -58
  12. package/src/components/checkpoint.stories.tsx +0 -102
  13. package/src/components/code-block.stories.tsx +0 -150
  14. package/src/components/confirm-card.stories.tsx +0 -74
  15. package/src/components/context.stories.tsx +0 -229
  16. package/src/components/context.test.tsx +0 -133
  17. package/src/components/conversation-item.stories.tsx +0 -125
  18. package/src/components/conversation-list.stories.tsx +0 -133
  19. package/src/components/default-input.test.tsx +0 -111
  20. package/src/components/empty.stories.tsx +0 -434
  21. package/src/components/feedback-bar.stories.tsx +0 -138
  22. package/src/components/feedback-bar.test.tsx +0 -103
  23. package/src/components/file-tree.stories.tsx +0 -73
  24. package/src/components/file-upload.stories.tsx +0 -156
  25. package/src/components/image.stories.tsx +0 -89
  26. package/src/components/loader.stories.tsx +0 -181
  27. package/src/components/markdown.stories.tsx +0 -180
  28. package/src/components/message-action-bar.test.tsx +0 -128
  29. package/src/components/message-narrow.stories.tsx +0 -329
  30. package/src/components/message-skills.stories.tsx +0 -211
  31. package/src/components/message.stories.tsx +0 -281
  32. package/src/components/model-switcher.stories.tsx +0 -123
  33. package/src/components/model-switcher.test.tsx +0 -65
  34. package/src/components/prompt-input.stories.tsx +0 -222
  35. package/src/components/prompt-suggestion.stories.tsx +0 -142
  36. package/src/components/reasoning.stories.tsx +0 -140
  37. package/src/components/resizable.test.tsx +0 -226
  38. package/src/components/scroll-button.stories.tsx +0 -100
  39. package/src/components/slash-command.stories.tsx +0 -163
  40. package/src/components/source-list.test.tsx +0 -152
  41. package/src/components/source.stories.tsx +0 -124
  42. package/src/components/tasks-card.stories.tsx +0 -78
  43. package/src/components/text-shimmer.stories.tsx +0 -87
  44. package/src/components/thinking-bar.stories.tsx +0 -87
  45. package/src/components/tool.stories.tsx +0 -153
  46. package/src/components/voice-input.stories.tsx +0 -83
  47. package/src/elements/artifact.stories.tsx +0 -506
  48. package/src/elements/attachments.stories.tsx +0 -190
  49. package/src/elements/card.stories.tsx +0 -113
  50. package/src/elements/cards.stories.tsx +0 -59
  51. package/src/elements/catalog.stories.tsx +0 -491
  52. package/src/elements/chain-of-thought.declarative.test.tsx +0 -153
  53. package/src/elements/chain-of-thought.stories.tsx +0 -113
  54. package/src/elements/chat-scope-picker.stories.tsx +0 -73
  55. package/src/elements/chat-workspace.stories.tsx +0 -288
  56. package/src/elements/chat.stories.tsx +0 -151
  57. package/src/elements/checkpoint.stories.tsx +0 -72
  58. package/src/elements/choice.stories.tsx +0 -240
  59. package/src/elements/code-block.stories.tsx +0 -83
  60. package/src/elements/composed-shell.stories.tsx +0 -316
  61. package/src/elements/confirm-card.stories.tsx +0 -227
  62. package/src/elements/context-meter.stories.tsx +0 -151
  63. package/src/elements/conversation-list.declarative.test.tsx +0 -137
  64. package/src/elements/conversation-list.stories.tsx +0 -243
  65. package/src/elements/embed.stories.tsx +0 -213
  66. package/src/elements/empty.stories.tsx +0 -111
  67. package/src/elements/feedback-bar.stories.tsx +0 -114
  68. package/src/elements/file-tree.stories.tsx +0 -134
  69. package/src/elements/file-upload.stories.tsx +0 -82
  70. package/src/elements/form.stories.tsx +0 -248
  71. package/src/elements/image.stories.tsx +0 -71
  72. package/src/elements/link-preview.stories.tsx +0 -209
  73. package/src/elements/loader.stories.tsx +0 -88
  74. package/src/elements/markdown.stories.tsx +0 -76
  75. package/src/elements/message-skills.declarative.test.tsx +0 -104
  76. package/src/elements/message-skills.stories.tsx +0 -114
  77. package/src/elements/message.stories.tsx +0 -218
  78. package/src/elements/model-switcher.declarative.test.tsx +0 -130
  79. package/src/elements/model-switcher.stories.tsx +0 -198
  80. package/src/elements/popover.stories.tsx +0 -80
  81. package/src/elements/prompt-input-slash-command.test.tsx +0 -128
  82. package/src/elements/prompt-input-stoppable.test.tsx +0 -88
  83. package/src/elements/prompt-input-toolbar-actions.test.tsx +0 -120
  84. package/src/elements/prompt-input.stories.tsx +0 -331
  85. package/src/elements/prompt-suggestions.declarative.test.tsx +0 -164
  86. package/src/elements/prompt-suggestions.stories.tsx +0 -213
  87. package/src/elements/reasoning.stories.tsx +0 -77
  88. package/src/elements/remote.stories.tsx +0 -314
  89. package/src/elements/resizable.stories.tsx +0 -426
  90. package/src/elements/response-stream.stories.tsx +0 -79
  91. package/src/elements/scroll-button.stories.tsx +0 -202
  92. package/src/elements/scroll-button.test.tsx +0 -148
  93. package/src/elements/source-list.stories.tsx +0 -143
  94. package/src/elements/source.stories.tsx +0 -88
  95. package/src/elements/switch.stories.tsx +0 -56
  96. package/src/elements/tasks.stories.tsx +0 -237
  97. package/src/elements/text-shimmer.stories.tsx +0 -64
  98. package/src/elements/thinking-bar.stories.tsx +0 -72
  99. package/src/elements/tool.stories.tsx +0 -89
  100. package/src/elements/voice-input.stories.tsx +0 -88
  101. package/src/primitives/controllable.test.ts +0 -47
  102. package/src/stories/chat-panel-layout.stories.tsx +0 -145
  103. package/src/stories/chat-scene.tsx +0 -571
  104. package/src/stories/checkpoint-restore.stories.tsx +0 -256
  105. package/src/stories/context-usage.stories.tsx +0 -212
  106. package/src/stories/conversation-with-reasoning.stories.tsx +0 -182
  107. package/src/stories/conversation-with-sources.stories.tsx +0 -471
  108. package/src/stories/docs/Accessibility.mdx +0 -119
  109. package/src/stories/docs/ChildElements.mdx +0 -269
  110. package/src/stories/docs/ForAIAgents.mdx +0 -162
  111. package/src/stories/docs/GettingStarted.mdx +0 -65
  112. package/src/stories/docs/Installation.mdx +0 -83
  113. package/src/stories/docs/Introduction.mdx +0 -50
  114. package/src/stories/docs/SolidJsAdvanced.mdx +0 -17
  115. package/src/stories/docs/Theming.mdx +0 -85
  116. package/src/stories/docs/element-controls.ts +0 -121
  117. package/src/stories/docs/frameworks/Angular.mdx +0 -245
  118. package/src/stories/docs/frameworks/Html.mdx +0 -227
  119. package/src/stories/docs/frameworks/Overview.mdx +0 -47
  120. package/src/stories/docs/frameworks/React.mdx +0 -227
  121. package/src/stories/docs/frameworks/Solid.mdx +0 -173
  122. package/src/stories/docs/frameworks/Svelte.mdx +0 -194
  123. package/src/stories/docs/frameworks/Vue.mdx +0 -238
  124. package/src/stories/docs/generative-ui-overview.mdx +0 -186
  125. package/src/stories/docs/recipes/SpeechToText.mdx +0 -7
  126. package/src/stories/docs/recipes/Streaming.mdx +0 -68
  127. package/src/stories/docs/recipes/TextToSpeech.mdx +0 -35
  128. package/src/stories/docs/theme-editor/canvas.tsx +0 -32
  129. package/src/stories/docs/theme-editor/inspector.tsx +0 -66
  130. package/src/stories/docs/theme-editor/presets.test.ts +0 -32
  131. package/src/stories/docs/theme-editor/presets.ts +0 -64
  132. package/src/stories/docs/theme-editor/theme-css.test.ts +0 -19
  133. package/src/stories/docs/theme-editor/theme-css.ts +0 -15
  134. package/src/stories/docs/theme-editor/theme-editor.tsx +0 -146
  135. package/src/stories/docs/theme-tokens.tsx +0 -174
  136. package/src/stories/examples/ChoosingComponents.mdx +0 -106
  137. package/src/stories/examples/sample-data.ts +0 -79
  138. package/src/stories/examples/usage/checkpoint-restore.ts +0 -156
  139. package/src/stories/examples/usage/context-usage.ts +0 -591
  140. package/src/stories/examples/usage/conversation-with-reasoning.ts +0 -224
  141. package/src/stories/examples/usage/conversation-with-sources.ts +0 -589
  142. package/src/stories/examples/usage/empty-state.ts +0 -144
  143. package/src/stories/examples/usage/full-chat-app.ts +0 -277
  144. package/src/stories/examples/usage/index.ts +0 -63
  145. package/src/stories/examples/usage/message-actions.ts +0 -704
  146. package/src/stories/examples/usage/pattern-centered-conversation.ts +0 -446
  147. package/src/stories/examples/usage/pattern-chat-panel-layout.ts +0 -442
  148. package/src/stories/examples/usage/pattern-docked-widget.ts +0 -479
  149. package/src/stories/examples/usage/prompt-input-variants.ts +0 -1356
  150. package/src/stories/examples/usage/streaming-response.ts +0 -687
  151. package/src/stories/examples/usage/types.ts +0 -33
  152. package/src/stories/full-chat.stories.tsx +0 -18
  153. package/src/stories/message-actions.stories.tsx +0 -230
  154. package/src/stories/pattern-centered-conversation.stories.tsx +0 -93
  155. package/src/stories/pattern-docked-widget.stories.tsx +0 -93
  156. package/src/stories/pattern-empty-state.stories.tsx +0 -76
  157. package/src/stories/prompt-input-variants.stories.tsx +0 -456
  158. package/src/stories/streaming-response.stories.tsx +0 -438
  159. package/src/stories/theme-editor.stories.tsx +0 -16
  160. package/src/stories/token-reference.stories.tsx +0 -18
  161. package/src/stories/typography.stories.tsx +0 -78
  162. package/src/ui/avatar.stories.tsx +0 -103
  163. package/src/ui/badge.stories.tsx +0 -86
  164. package/src/ui/button.stories.tsx +0 -145
  165. package/src/ui/collapsible.stories.tsx +0 -69
  166. package/src/ui/dropdown.stories.tsx +0 -59
  167. package/src/ui/hover-card.stories.tsx +0 -77
  168. package/src/ui/hover-card.test.tsx +0 -30
  169. package/src/ui/overlay.stories.tsx +0 -115
  170. package/src/ui/popover.stories.tsx +0 -81
  171. package/src/ui/popover.test.tsx +0 -99
  172. package/src/ui/resizable.stories.tsx +0 -236
  173. package/src/ui/scroll-area.stories.tsx +0 -50
  174. package/src/ui/separator.stories.tsx +0 -81
  175. package/src/ui/skeleton.stories.tsx +0 -337
  176. package/src/ui/switch.stories.tsx +0 -51
  177. package/src/ui/switch.test.tsx +0 -59
  178. package/src/ui/textarea.stories.tsx +0 -76
  179. package/src/ui/tooltip.stories.tsx +0 -74
@@ -1,144 +0,0 @@
1
- import type { ExampleUsage, StoryUsage } from './types';
2
-
3
- /** New Chat — a centered greeting (icon + title + description), starter suggestion chips, and a composer. */
4
- const newChat: StoryUsage = {
5
- intro:
6
- "The new-chat zero state. `<kai-empty>` renders the centered greeting from two scalar props — `emptyTitle` (DOM attribute `empty-title`, since `title` is a global HTML attribute) and `description`. The icon, the starter suggestion chips, and the composer below aren't part of `<kai-empty>` — compose those with the SolidJS `Empty` + `PromptSuggestion` + `PromptInput` primitives (see the Solid tab).",
7
- snippets: {
8
- html: `<!-- Register the elements once (CDN or bundler) -->
9
- <script type="module">
10
- import 'https://cdn.jsdelivr.net/npm/@kitn.ai/ui/dist/kitn-chat.es.js';
11
- </script>
12
-
13
- <!-- Scalars are plain attributes. Note the kebab-case empty-title. -->
14
- <kai-empty
15
- empty-title="How can I help today?"
16
- description="Ask anything, or start from one of these."
17
- ></kai-empty>
18
-
19
- <!-- The icon, suggestion chips, and composer are not part of <kai-empty>;
20
- compose them yourself (see the Solid tab). -->`,
21
-
22
- react: `import { Empty } from '@kitn.ai/ui/react';
23
-
24
- export function NewChat() {
25
- // Icon, suggestion chips, and composer aren't props on <Empty> —
26
- // compose them yourself (see the Solid tab).
27
- return (
28
- <Empty
29
- emptyTitle="How can I help today?"
30
- description="Ask anything, or start from one of these."
31
- />
32
- );
33
- }`,
34
-
35
- vue: `<script setup>
36
- import '@kitn.ai/ui/elements'; // register once (e.g. in main.ts)
37
- </script>
38
-
39
- <template>
40
- <!-- Scalars as plain attributes; empty-title is kebab-case. -->
41
- <kai-empty
42
- empty-title="How can I help today?"
43
- description="Ask anything, or start from one of these."
44
- />
45
- <!-- Icon, suggestions, and composer are composed separately. -->
46
- </template>`,
47
-
48
- svelte: `<script>
49
- import '@kitn.ai/ui/elements'; // register once
50
- </script>
51
-
52
- <!-- Scalars as attributes; empty-title is kebab-case. -->
53
- <kai-empty
54
- empty-title="How can I help today?"
55
- description="Ask anything, or start from one of these."
56
- ></kai-empty>
57
- <!-- Icon, suggestions, and composer are composed separately. -->`,
58
-
59
- angular: `// main.ts: import '@kitn.ai/ui/elements' before bootstrapApplication,
60
- // and add CUSTOM_ELEMENTS_SCHEMA to the component.
61
- import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
62
-
63
- @Component({
64
- selector: 'app-new-chat',
65
- standalone: true,
66
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
67
- // empty-title is kebab-case; both props are scalar strings.
68
- template: \`
69
- <kai-empty
70
- empty-title="How can I help today?"
71
- description="Ask anything, or start from one of these."
72
- ></kai-empty>
73
- \`,
74
- })
75
- export class NewChatComponent {}`,
76
-
77
- solid: `import { createSignal } from 'solid-js';
78
- import {
79
- ChatConfig, Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
80
- PromptSuggestion, PromptInput, PromptInputTextarea, PromptInputActions, Button,
81
- } from '@kitn.ai/ui';
82
- import { Sparkles, Plus, Globe, ArrowUp } from 'lucide-solid';
83
-
84
- const SUGGESTIONS = [
85
- 'Summarize a document',
86
- 'Draft a product update',
87
- 'Explain a code snippet',
88
- 'Plan my week',
89
- ];
90
-
91
- export function NewChat() {
92
- const [input, setInput] = createSignal('');
93
- return (
94
- <ChatConfig proseSize="base">
95
- <Empty class="flex-1">
96
- <EmptyHeader>
97
- <EmptyMedia variant="icon"><Sparkles class="size-6" /></EmptyMedia>
98
- <EmptyTitle>How can I help today?</EmptyTitle>
99
- <EmptyDescription>Ask anything, or start from one of these.</EmptyDescription>
100
- </EmptyHeader>
101
- <EmptyContent>
102
- <div class="flex max-w-md flex-wrap justify-center gap-2">
103
- {SUGGESTIONS.map((s) => (
104
- <PromptSuggestion onClick={() => setInput(s)}>{s}</PromptSuggestion>
105
- ))}
106
- </div>
107
- </EmptyContent>
108
- </Empty>
109
-
110
- {/* Composer fills from a clicked suggestion. */}
111
- <PromptInput value={input()} onValueChange={setInput} onSubmit={() => setInput('')}>
112
- <PromptInputTextarea placeholder="Ask anything…" />
113
- <PromptInputActions class="flex items-center justify-between gap-2">
114
- <div class="flex items-center gap-2">
115
- <Button variant="outline" size="icon-sm" class="rounded-full" aria-label="Add"><Plus class="size-4" /></Button>
116
- <Button variant="outline" size="sm" class="rounded-full gap-1" aria-label="Search the web"><Globe class="size-4" />Search</Button>
117
- </div>
118
- <Button size="icon-sm" class="rounded-full" disabled={!input().trim()} aria-label="Send message">
119
- <ArrowUp class="size-4" />
120
- </Button>
121
- </PromptInputActions>
122
- </PromptInput>
123
- </ChatConfig>
124
- );
125
- }`,
126
- },
127
- };
128
-
129
- /**
130
- * Pattern: Empty State — the new-chat zero state. `<kai-empty>` covers the
131
- * centered greeting (`emptyTitle` + `description`); the icon, starter
132
- * suggestion chips, and composer are SolidJS primitive composition. Per-story:
133
- * the Usage tab shows the snippet for the story you're on; the example-level
134
- * fields below are the fallback.
135
- */
136
- const emptyState: ExampleUsage = {
137
- title: 'Patterns/Empty State',
138
- ...newChat, // example-level fallback = the primary "New Chat" story
139
- stories: {
140
- 'New Chat': newChat,
141
- },
142
- };
143
-
144
- export default emptyState;
@@ -1,277 +0,0 @@
1
- import type { ExampleUsage, StoryUsage } from './types';
2
-
3
- // A small thread reused across the snippets — user + assistant, with actions,
4
- // reasoning, and a tool call on the second assistant message.
5
- const MESSAGES = `[
6
- { id: 'u1', role: 'user', content: 'Can you explain how SolidJS reactivity differs from React hooks?' },
7
- {
8
- id: 'a1',
9
- role: 'assistant',
10
- content: 'SolidJS uses fine-grained signals: components run once and only the DOM nodes that read a signal update.',
11
- actions: ['copy', 'like', 'dislike', 'regenerate'],
12
- },
13
- { id: 'u2', role: 'user', content: 'Can you benchmark SolidJS vs React for 10,000 items?' },
14
- {
15
- id: 'a2',
16
- role: 'assistant',
17
- content: 'Here are the benchmark results — SolidJS renders ~7x faster and updates ~42x faster.',
18
- actions: ['copy', 'like', 'dislike', 'regenerate'],
19
- reasoning: { label: 'Thought for 4 seconds', text: 'Render the same 10,000 items in both frameworks for a fair comparison.' },
20
- tools: [
21
- {
22
- type: 'run_benchmark',
23
- state: 'output-available',
24
- input: { framework: ['solid', 'react'], itemCount: 10000 },
25
- output: { solid: { avgRenderMs: 12.4 }, react: { avgRenderMs: 89.2 } },
26
- toolCallId: 'call_abc123',
27
- },
28
- ],
29
- },
30
- ]`;
31
-
32
- const MODELS = `[
33
- { id: 'claude-4', name: 'Claude 4 Opus', provider: 'Anthropic' },
34
- { id: 'gpt-4o', name: 'GPT-4o', provider: 'OpenAI' },
35
- ]`;
36
-
37
- const CONTEXT = `{ usedTokens: 12400, maxTokens: 200000, inputTokens: 8200, outputTokens: 4200, estimatedCost: 0.042 }`;
38
-
39
- const SUGGESTIONS = `['How does SolidJS handle context?', 'Show me a store example']`;
40
-
41
- /**
42
- * Default — the entire chat experience in one element. `<kai-chat>` renders the
43
- * message thread (markdown, reasoning, tool calls, per-message action bars), a
44
- * header with the `models` switcher + `context` token meter, the `suggestions`
45
- * chips, and the prompt input. The demo's resizable sidebar + conversation list
46
- * are separate chrome that lives *outside* the element.
47
- */
48
- const fullChat: StoryUsage = {
49
- intro:
50
- 'Drop in the whole chat experience with one element. `<kai-chat>` renders the thread (markdown, reasoning, tool calls, action bars), an optional header model switcher + `context` token meter, `suggestions` chips, and the prompt input — set `messages` as a property and handle `submit` / `messageaction` / `modelchange`. The resizable conversation sidebar in the demo is separate chrome `<kai-chat>` does not include. (The live demo composes the SolidJS `ChatContainer`, `Message`, `PromptInput`, and `ConversationList` primitives directly.)',
51
- snippets: {
52
- html: `<!-- Register the elements once (CDN or bundler) -->
53
- <script type="module">
54
- import 'https://cdn.jsdelivr.net/npm/@kitn.ai/ui/dist/kitn-chat.es.js';
55
- </script>
56
-
57
- <kai-chat
58
- id="chat"
59
- chat-title="SolidJS reactivity vs React hooks"
60
- current-model="claude-4"
61
- prose-size="base"
62
- placeholder="Ask anything..."
63
- ></kai-chat>
64
-
65
- <script type="module">
66
- const chat = document.getElementById('chat');
67
-
68
- // Object/array props are set as PROPERTIES, not attributes.
69
- chat.messages = ${MESSAGES};
70
- chat.models = ${MODELS};
71
- chat.context = ${CONTEXT};
72
- chat.suggestions = ${SUGGESTIONS};
73
-
74
- chat.addEventListener('kai-submit', (e) => {
75
- const { value, attachments } = e.detail; // append the user message / call your backend
76
- console.log('send', value, attachments);
77
- });
78
- chat.addEventListener('kai-message-action', (e) => {
79
- const { messageId, action } = e.detail; // 'copy' | 'like' | 'dislike' | 'regenerate' | 'edit'
80
- console.log(messageId, action);
81
- });
82
- chat.addEventListener('kai-model-change', (e) => console.log(e.detail.modelId));
83
- </script>`,
84
-
85
- react: `import { Chat } from '@kitn.ai/ui/react';
86
-
87
- export function ChatApp() {
88
- return (
89
- <Chat
90
- chatTitle="SolidJS reactivity vs React hooks"
91
- proseSize="base"
92
- placeholder="Ask anything..."
93
- currentModel="claude-4"
94
- models={${MODELS}}
95
- context={${CONTEXT}}
96
- suggestions={${SUGGESTIONS}}
97
- messages={${MESSAGES}}
98
- onSubmit={(e) => console.log('send', e.detail.value, e.detail.attachments)}
99
- onMessageAction={(e) => console.log(e.detail.messageId, e.detail.action)}
100
- onModelChange={(e) => console.log(e.detail.modelId)}
101
- />
102
- );
103
- }`,
104
-
105
- vue: `<script setup>
106
- import '@kitn.ai/ui/elements'; // register once (e.g. in main.ts)
107
-
108
- // Object/array props use the .prop modifier in the template.
109
- const messages = ${MESSAGES};
110
- const models = ${MODELS};
111
- const context = ${CONTEXT};
112
- const suggestions = ${SUGGESTIONS};
113
-
114
- function onSubmit(e) { console.log('send', e.detail.value, e.detail.attachments); }
115
- function onAction(e) { console.log(e.detail.messageId, e.detail.action); }
116
- </script>
117
-
118
- <template>
119
- <kai-chat
120
- chat-title="SolidJS reactivity vs React hooks"
121
- prose-size="base"
122
- placeholder="Ask anything..."
123
- current-model="claude-4"
124
- :messages.prop="messages"
125
- :models.prop="models"
126
- :context.prop="context"
127
- :suggestions.prop="suggestions"
128
- @kai-submit="onSubmit"
129
- @kai-message-action="onAction"
130
- @kai-model-change="(e) => console.log(e.detail.modelId)"
131
- />
132
- </template>`,
133
-
134
- svelte: `<script>
135
- import '@kitn.ai/ui/elements';
136
-
137
- let el;
138
- // Object/array props are set as properties via bind:this.
139
- const messages = ${MESSAGES};
140
- const models = ${MODELS};
141
- const context = ${CONTEXT};
142
- const suggestions = ${SUGGESTIONS};
143
- $: if (el) {
144
- el.messages = messages;
145
- el.models = models;
146
- el.context = context;
147
- el.suggestions = suggestions;
148
- }
149
-
150
- function onSubmit(e) { console.log('send', e.detail.value, e.detail.attachments); }
151
- function onAction(e) { console.log(e.detail.messageId, e.detail.action); }
152
- </script>
153
-
154
- <kai-chat
155
- bind:this={el}
156
- chat-title="SolidJS reactivity vs React hooks"
157
- prose-size="base"
158
- placeholder="Ask anything..."
159
- current-model="claude-4"
160
- on:kai-submit={onSubmit}
161
- on:kai-message-action={onAction}
162
- on:kai-model-change={(e) => console.log(e.detail.modelId)}
163
- />`,
164
-
165
- angular: `// main.ts: import '@kitn.ai/ui/elements' before bootstrapApplication,
166
- // and add CUSTOM_ELEMENTS_SCHEMA to the component.
167
- import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
168
-
169
- @Component({
170
- selector: 'app-chat',
171
- standalone: true,
172
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
173
- template: \`
174
- <kai-chat
175
- chat-title="SolidJS reactivity vs React hooks"
176
- prose-size="base"
177
- placeholder="Ask anything..."
178
- current-model="claude-4"
179
- [messages]="messages"
180
- [models]="models"
181
- [context]="context"
182
- [suggestions]="suggestions"
183
- (kai-submit)="onSubmit($event)"
184
- (kai-message-action)="onAction($event)"
185
- (kai-model-change)="onModel($event)"
186
- ></kai-chat>
187
- \`,
188
- })
189
- export class ChatComponent {
190
- messages = ${MESSAGES};
191
- models = ${MODELS};
192
- context = ${CONTEXT};
193
- suggestions = ${SUGGESTIONS};
194
- onSubmit(e: CustomEvent<{ value: string; attachments: unknown[] }>) {
195
- console.log('send', e.detail.value, e.detail.attachments);
196
- }
197
- onAction(e: CustomEvent<{ messageId: string; action: string }>) {
198
- console.log(e.detail.messageId, e.detail.action);
199
- }
200
- onModel(e: CustomEvent<{ modelId: string }>) { console.log(e.detail.modelId); }
201
- }`,
202
-
203
- solid: `import { createSignal, For } from 'solid-js';
204
- import {
205
- ChatContainer, ChatContainerContent, ChatContainerScrollAnchor,
206
- Message, MessageContent, MessageActions,
207
- PromptInput, PromptInputTextarea, PromptInputActions,
208
- ConversationList, ModelSwitcher, PromptSuggestion, ScrollButton, Button,
209
- } from '@kitn.ai/ui';
210
- import { Copy, ThumbsUp, ThumbsDown, RefreshCw, ArrowUp } from 'lucide-solid';
211
-
212
- export function ChatApp() {
213
- const [value, setValue] = createSignal('');
214
- const [modelId, setModelId] = createSignal('claude-4');
215
-
216
- return (
217
- <div class="flex h-screen w-full bg-background">
218
- {/* Sidebar — separate chrome from the thread */}
219
- <ConversationList groups={groups} conversations={conversations} activeId="1" onSelect={() => {}} onNewChat={() => {}} />
220
-
221
- <main class="flex flex-1 flex-col overflow-hidden">
222
- <header class="flex h-14 items-center justify-between border-b border-border px-5">
223
- <div class="text-sm font-semibold">SolidJS reactivity vs React hooks</div>
224
- <ModelSwitcher models={models} currentModelId={modelId()} onModelChange={setModelId} />
225
- </header>
226
-
227
- <ChatContainer class="flex-1">
228
- <ChatContainerContent class="px-5 pt-4">
229
- <Message class="group items-start">
230
- <MessageContent markdown class="prose">{assistantReply}</MessageContent>
231
- <MessageActions class="opacity-0 group-hover:opacity-100 transition-opacity">
232
- <Button variant="ghost" size="icon-sm" aria-label="Copy"><Copy class="size-3.5" /></Button>
233
- <Button variant="ghost" size="icon-sm" aria-label="Good response"><ThumbsUp class="size-3.5" /></Button>
234
- <Button variant="ghost" size="icon-sm" aria-label="Bad response"><ThumbsDown class="size-3.5" /></Button>
235
- <Button variant="ghost" size="icon-sm" aria-label="Regenerate"><RefreshCw class="size-3.5" /></Button>
236
- </MessageActions>
237
- </Message>
238
- <ChatContainerScrollAnchor />
239
- </ChatContainerContent>
240
- <ScrollButton />
241
- </ChatContainer>
242
-
243
- <div class="px-5 pb-5">
244
- <div class="flex gap-2 pb-3">
245
- <For each={['How does SolidJS handle context?', 'Show me a store example']}>
246
- {(s) => <PromptSuggestion onClick={() => setValue(s)}>{s}</PromptSuggestion>}
247
- </For>
248
- </div>
249
- <PromptInput value={value()} onValueChange={setValue} onSubmit={() => setValue('')}>
250
- <PromptInputTextarea placeholder="Ask anything..." />
251
- <PromptInputActions class="justify-end">
252
- <Button size="icon-sm" disabled={!value().trim()} aria-label="Send message"><ArrowUp class="size-4" /></Button>
253
- </PromptInputActions>
254
- </PromptInput>
255
- </div>
256
- </main>
257
- </div>
258
- );
259
- }`,
260
- },
261
- };
262
-
263
- /**
264
- * Example: Full Chat App — the complete experience. As an embedder you reach for
265
- * the single `<kai-chat>` element; the live demo composes the granular SolidJS
266
- * primitives for full control. Per-story: the Usage tab shows the snippet for the
267
- * story you're on; the example-level fields below are the fallback.
268
- */
269
- const fullChatApp: ExampleUsage = {
270
- title: 'Examples/Full Chat App',
271
- ...fullChat, // example-level fallback = the "Default" story
272
- stories: {
273
- Default: fullChat,
274
- },
275
- };
276
-
277
- export default fullChatApp;
@@ -1,63 +0,0 @@
1
- import type { ExampleUsage } from './types';
2
- import messageActions from './message-actions';
3
- import streamingResponse from './streaming-response';
4
- import conversationWithReasoning from './conversation-with-reasoning';
5
- import conversationWithSources from './conversation-with-sources';
6
- import promptInputVariants from './prompt-input-variants';
7
- import contextUsage from './context-usage';
8
- import checkpointRestore from './checkpoint-restore';
9
- import fullChatApp from './full-chat-app';
10
- import emptyState from './empty-state';
11
- import centeredConversation from './pattern-centered-conversation';
12
- import chatPanelLayout from './pattern-chat-panel-layout';
13
- import dockedWidget from './pattern-docked-widget';
14
-
15
- export type { ExampleUsage, FrameworkKey } from './types';
16
-
17
- /**
18
- * Every Example/Pattern that has hand-authored "how to build this" code.
19
- * Add a module here and it lights up its Code tab automatically.
20
- *
21
- * Element-centric examples first, then the 4 layout Patterns — each pattern
22
- * module carries a `title` that exactly matches its Storybook group title so
23
- * the Usage tab appears automatically via `exampleUsageStoryIdPrefixes`.
24
- */
25
- export const exampleUsageList: ExampleUsage[] = [
26
- messageActions,
27
- streamingResponse,
28
- conversationWithReasoning,
29
- conversationWithSources,
30
- promptInputVariants,
31
- contextUsage,
32
- checkpointRestore,
33
- fullChatApp,
34
- // Patterns — layout recipes showing how to compose the building blocks
35
- emptyState,
36
- centeredConversation,
37
- chatPanelLayout,
38
- dockedWidget,
39
- ];
40
-
41
- /** Lookup by Storybook group title, e.g. `'Examples/Message Actions'`. */
42
- export const exampleUsageByTitle = new Map(exampleUsageList.map((u) => [u.title, u]));
43
-
44
- /**
45
- * Storybook's `sanitize` (from `@storybook/csf`), inlined so the manager addon
46
- * has no extra dependency. Turns a title into its story-id stem, e.g.
47
- * `'Examples/Message Actions'` → `'examples-message-actions'`.
48
- */
49
- const sanitize = (s: string): string =>
50
- s
51
- .toLowerCase()
52
- .replace(/[ ’–—―′¿'`~!@#$%^&*()_|+\-=?;:'",.<>{}[\]\\/]/g, '-')
53
- .replace(/-+/g, '-')
54
- .replace(/^-+/, '')
55
- .replace(/-+$/, '');
56
-
57
- /**
58
- * Story-id prefixes (`<stem>--`) for entries that have a Code tab. `manager.ts`
59
- * uses these to show the tab only where we've authored code.
60
- */
61
- export const exampleUsageStoryIdPrefixes: string[] = exampleUsageList.map(
62
- (u) => `${sanitize(u.title)}--`,
63
- );