@kitn.ai/ui 0.14.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.
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/dist/bash-InADTalH.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -0
- package/dist/css-M7EaDHN_.js +1 -0
- package/dist/custom-elements.json +4739 -0
- package/dist/engine-javascript-vq0WuIJl.js +141 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -0
- package/dist/github-light-JYsPkUQd.js +1 -0
- package/dist/host-embed.d.ts +33 -0
- package/dist/html-CPZ3oZQ7.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/javascript-C25yR2R2.js +1 -0
- package/dist/json-DxJze_jm.js +1 -0
- package/dist/kitn-chat-provider.d.ts +2 -0
- package/dist/kitn-chat-provider.es.js +240 -0
- package/dist/kitn-chat.es.js +77 -0
- package/dist/llms/llms-full.txt +1018 -0
- package/dist/llms/llms.txt +104 -0
- package/dist/origin.d.ts +5 -0
- package/dist/provider-runtime.d.ts +27 -0
- package/dist/schemas/card-envelope.schema.json +14 -0
- package/dist/schemas/card-event.schema.json +12 -0
- package/dist/schemas/choice.schema.json +70 -0
- package/dist/schemas/confirm.schema.json +65 -0
- package/dist/schemas/embed.schema.json +65 -0
- package/dist/schemas/form.result.schema.json +7 -0
- package/dist/schemas/form.schema.json +33 -0
- package/dist/schemas/link.schema.json +56 -0
- package/dist/schemas/tasks.result.schema.json +16 -0
- package/dist/schemas/tasks.schema.json +78 -0
- package/dist/svelte--5p79yCD.js +1 -0
- package/dist/theme.tokens.css +176 -0
- package/dist/tsx-B8rCNbgL.js +1 -0
- package/dist/typescript-RycA9KXf.js +1 -0
- package/dist/validate.d.ts +4 -0
- package/dist/version.d.ts +4 -0
- package/dist/vue-BmIZj4XD.js +1 -0
- package/dist/wire.d.ts +53 -0
- package/frameworks/react/index.tsx +948 -0
- package/frameworks/react/runtime.tsx +94 -0
- package/llms-full.txt +1018 -0
- package/llms.txt +104 -0
- package/package.json +141 -0
- package/src/components/artifact.stories.tsx +138 -0
- package/src/components/artifact.tsx +743 -0
- package/src/components/attachments.stories.tsx +303 -0
- package/src/components/attachments.test.tsx +64 -0
- package/src/components/attachments.tsx +399 -0
- package/src/components/card-fallback.tsx +28 -0
- package/src/components/card-renderer.tsx +52 -0
- package/src/components/card.tsx +110 -0
- package/src/components/chain-of-thought.stories.tsx +211 -0
- package/src/components/chain-of-thought.tsx +139 -0
- package/src/components/chat-container.stories.tsx +187 -0
- package/src/components/chat-container.tsx +82 -0
- package/src/components/chat-scope-picker.tsx +47 -0
- package/src/components/chat-thread.test.tsx +58 -0
- package/src/components/chat-thread.tsx +249 -0
- package/src/components/checkpoint.stories.tsx +102 -0
- package/src/components/checkpoint.tsx +88 -0
- package/src/components/choice-card.tsx +569 -0
- package/src/components/code-block.stories.tsx +150 -0
- package/src/components/code-block.tsx +105 -0
- package/src/components/component-meta.json +3735 -0
- package/src/components/confirm-card.stories.tsx +74 -0
- package/src/components/confirm-card.tsx +315 -0
- package/src/components/context.stories.tsx +229 -0
- package/src/components/context.test.tsx +133 -0
- package/src/components/context.tsx +363 -0
- package/src/components/conversation-item.stories.tsx +125 -0
- package/src/components/conversation-item.tsx +16 -0
- package/src/components/conversation-list.stories.tsx +133 -0
- package/src/components/conversation-list.tsx +101 -0
- package/src/components/default-input.test.tsx +111 -0
- package/src/components/embed.tsx +196 -0
- package/src/components/empty.stories.tsx +434 -0
- package/src/components/empty.tsx +166 -0
- package/src/components/feedback-bar.stories.tsx +138 -0
- package/src/components/feedback-bar.test.tsx +103 -0
- package/src/components/feedback-bar.tsx +166 -0
- package/src/components/file-tree.stories.tsx +73 -0
- package/src/components/file-tree.tsx +383 -0
- package/src/components/file-upload.stories.tsx +156 -0
- package/src/components/file-upload.tsx +161 -0
- package/src/components/form-widgets.tsx +461 -0
- package/src/components/form.tsx +873 -0
- package/src/components/image.stories.tsx +89 -0
- package/src/components/image.tsx +67 -0
- package/src/components/link-preview.tsx +194 -0
- package/src/components/loader.stories.tsx +181 -0
- package/src/components/loader.tsx +333 -0
- package/src/components/markdown.stories.tsx +180 -0
- package/src/components/markdown.tsx +81 -0
- package/src/components/message-action-bar.test.tsx +128 -0
- package/src/components/message-narrow.stories.tsx +329 -0
- package/src/components/message-skills.stories.tsx +211 -0
- package/src/components/message-skills.tsx +36 -0
- package/src/components/message.stories.tsx +281 -0
- package/src/components/message.tsx +227 -0
- package/src/components/model-switcher.stories.tsx +123 -0
- package/src/components/model-switcher.test.tsx +65 -0
- package/src/components/model-switcher.tsx +87 -0
- package/src/components/prompt-input.stories.tsx +222 -0
- package/src/components/prompt-input.tsx +211 -0
- package/src/components/prompt-suggestion.stories.tsx +142 -0
- package/src/components/prompt-suggestion.tsx +115 -0
- package/src/components/reasoning.stories.tsx +140 -0
- package/src/components/reasoning.tsx +156 -0
- package/src/components/resizable.test.tsx +226 -0
- package/src/components/response-stream.tsx +103 -0
- package/src/components/scroll-button.stories.tsx +100 -0
- package/src/components/scroll-button.tsx +34 -0
- package/src/components/slash-command.stories.tsx +163 -0
- package/src/components/slash-command.tsx +232 -0
- package/src/components/source-list.test.tsx +152 -0
- package/src/components/source.stories.tsx +124 -0
- package/src/components/source.tsx +129 -0
- package/src/components/tasks-card.stories.tsx +78 -0
- package/src/components/tasks-card.tsx +432 -0
- package/src/components/text-shimmer.stories.tsx +87 -0
- package/src/components/text-shimmer.tsx +37 -0
- package/src/components/thinking-bar.stories.tsx +87 -0
- package/src/components/thinking-bar.tsx +50 -0
- package/src/components/tool.stories.tsx +153 -0
- package/src/components/tool.tsx +184 -0
- package/src/components/use-card-resolution.ts +28 -0
- package/src/components/voice-input.stories.tsx +83 -0
- package/src/components/voice-input.tsx +107 -0
- package/src/elements/artifact.stories.tsx +506 -0
- package/src/elements/artifact.tsx +137 -0
- package/src/elements/attachments.stories.tsx +190 -0
- package/src/elements/attachments.tsx +136 -0
- package/src/elements/card.stories.tsx +113 -0
- package/src/elements/card.tsx +40 -0
- package/src/elements/cards.stories.tsx +59 -0
- package/src/elements/cards.tsx +97 -0
- package/src/elements/catalog.stories.tsx +491 -0
- package/src/elements/chain-of-thought.declarative.test.tsx +153 -0
- package/src/elements/chain-of-thought.stories.tsx +113 -0
- package/src/elements/chain-of-thought.tsx +92 -0
- package/src/elements/chat-scope-picker.stories.tsx +73 -0
- package/src/elements/chat-scope-picker.tsx +36 -0
- package/src/elements/chat-types.ts +42 -0
- package/src/elements/chat-workspace.stories.tsx +288 -0
- package/src/elements/chat-workspace.tsx +161 -0
- package/src/elements/chat.stories.tsx +151 -0
- package/src/elements/chat.tsx +80 -0
- package/src/elements/checkpoint.stories.tsx +72 -0
- package/src/elements/checkpoint.tsx +47 -0
- package/src/elements/choice.stories.tsx +240 -0
- package/src/elements/choice.tsx +48 -0
- package/src/elements/code-block.stories.tsx +83 -0
- package/src/elements/code-block.tsx +42 -0
- package/src/elements/compiled.css +2 -0
- package/src/elements/composed-shell.stories.tsx +316 -0
- package/src/elements/confirm-card.stories.tsx +227 -0
- package/src/elements/confirm-card.tsx +51 -0
- package/src/elements/context-meter.stories.tsx +151 -0
- package/src/elements/context-meter.tsx +121 -0
- package/src/elements/conversation-list.declarative.test.tsx +137 -0
- package/src/elements/conversation-list.stories.tsx +243 -0
- package/src/elements/conversation-list.tsx +80 -0
- package/src/elements/css.ts +5 -0
- package/src/elements/default-input.tsx +247 -0
- package/src/elements/define.tsx +171 -0
- package/src/elements/element-meta.json +3314 -0
- package/src/elements/element-types.d.ts +710 -0
- package/src/elements/embed.stories.tsx +213 -0
- package/src/elements/embed.tsx +35 -0
- package/src/elements/empty.stories.tsx +111 -0
- package/src/elements/empty.tsx +29 -0
- package/src/elements/feedback-bar.stories.tsx +114 -0
- package/src/elements/feedback-bar.tsx +61 -0
- package/src/elements/file-tree.stories.tsx +134 -0
- package/src/elements/file-tree.tsx +52 -0
- package/src/elements/file-upload.stories.tsx +82 -0
- package/src/elements/file-upload.tsx +44 -0
- package/src/elements/form.stories.tsx +248 -0
- package/src/elements/form.tsx +43 -0
- package/src/elements/framework-usage.json +563 -0
- package/src/elements/image.stories.tsx +71 -0
- package/src/elements/image.tsx +32 -0
- package/src/elements/link-preview.stories.tsx +209 -0
- package/src/elements/link-preview.tsx +34 -0
- package/src/elements/loader.stories.tsx +88 -0
- package/src/elements/loader.tsx +25 -0
- package/src/elements/markdown.stories.tsx +76 -0
- package/src/elements/markdown.tsx +38 -0
- package/src/elements/message-skills.declarative.test.tsx +104 -0
- package/src/elements/message-skills.stories.tsx +114 -0
- package/src/elements/message-skills.tsx +85 -0
- package/src/elements/message.stories.tsx +218 -0
- package/src/elements/message.tsx +162 -0
- package/src/elements/model-switcher.declarative.test.tsx +130 -0
- package/src/elements/model-switcher.stories.tsx +198 -0
- package/src/elements/model-switcher.tsx +93 -0
- package/src/elements/popover.stories.tsx +80 -0
- package/src/elements/popover.tsx +59 -0
- package/src/elements/prompt-input-slash-command.test.tsx +128 -0
- package/src/elements/prompt-input-stoppable.test.tsx +88 -0
- package/src/elements/prompt-input-toolbar-actions.test.tsx +120 -0
- package/src/elements/prompt-input.stories.tsx +331 -0
- package/src/elements/prompt-input.tsx +185 -0
- package/src/elements/prompt-suggestions.declarative.test.tsx +164 -0
- package/src/elements/prompt-suggestions.stories.tsx +213 -0
- package/src/elements/prompt-suggestions.tsx +94 -0
- package/src/elements/reasoning.stories.tsx +77 -0
- package/src/elements/reasoning.tsx +50 -0
- package/src/elements/register.ts +56 -0
- package/src/elements/remote.stories.tsx +314 -0
- package/src/elements/remote.tsx +221 -0
- package/src/elements/resizable.d.ts +27 -0
- package/src/elements/resizable.stories.tsx +426 -0
- package/src/elements/resizable.tsx +553 -0
- package/src/elements/response-stream.stories.tsx +79 -0
- package/src/elements/response-stream.tsx +40 -0
- package/src/elements/scroll-button.stories.tsx +202 -0
- package/src/elements/scroll-button.test.tsx +148 -0
- package/src/elements/scroll-button.tsx +126 -0
- package/src/elements/source-list.stories.tsx +143 -0
- package/src/elements/source.stories.tsx +88 -0
- package/src/elements/source.tsx +120 -0
- package/src/elements/styles.css +199 -0
- package/src/elements/switch.stories.tsx +56 -0
- package/src/elements/switch.tsx +43 -0
- package/src/elements/tasks.stories.tsx +237 -0
- package/src/elements/tasks.tsx +46 -0
- package/src/elements/text-shimmer.stories.tsx +64 -0
- package/src/elements/text-shimmer.tsx +28 -0
- package/src/elements/thinking-bar.stories.tsx +72 -0
- package/src/elements/thinking-bar.tsx +34 -0
- package/src/elements/tool.stories.tsx +89 -0
- package/src/elements/tool.tsx +23 -0
- package/src/elements/voice-input.stories.tsx +88 -0
- package/src/elements/voice-input.tsx +41 -0
- package/src/index.ts +253 -0
- package/src/primitives/card-contract.ts +71 -0
- package/src/primitives/card-host.tsx +35 -0
- package/src/primitives/card-registry.tsx +67 -0
- package/src/primitives/card-resolution.ts +36 -0
- package/src/primitives/card-routing.ts +79 -0
- package/src/primitives/card-schemas/card-envelope.schema.json +14 -0
- package/src/primitives/card-schemas/card-event.schema.json +12 -0
- package/src/primitives/card-schemas/choice.schema.json +70 -0
- package/src/primitives/card-schemas/confirm.schema.json +65 -0
- package/src/primitives/card-schemas/embed.schema.json +65 -0
- package/src/primitives/card-schemas/form.result.schema.json +7 -0
- package/src/primitives/card-schemas/form.schema.json +33 -0
- package/src/primitives/card-schemas/link.schema.json +56 -0
- package/src/primitives/card-schemas/tasks.result.schema.json +16 -0
- package/src/primitives/card-schemas/tasks.schema.json +78 -0
- package/src/primitives/card-validate.ts +95 -0
- package/src/primitives/chat-config.tsx +76 -0
- package/src/primitives/controllable.test.ts +47 -0
- package/src/primitives/controllable.ts +21 -0
- package/src/primitives/embed-providers.ts +254 -0
- package/src/primitives/highlighter.ts +157 -0
- package/src/primitives/link-preview.ts +87 -0
- package/src/primitives/pdf-preview.ts +121 -0
- package/src/primitives/use-auto-resize.ts +31 -0
- package/src/primitives/use-resize-observer.ts +12 -0
- package/src/primitives/use-stick-to-bottom.ts +43 -0
- package/src/primitives/use-text-stream.ts +112 -0
- package/src/primitives/use-voice-recorder.ts +50 -0
- package/src/remote/host-embed.ts +345 -0
- package/src/remote/index.ts +2 -0
- package/src/remote/origin.ts +30 -0
- package/src/remote/provider-runtime.ts +259 -0
- package/src/remote/provider.ts +2 -0
- package/src/remote/validate.ts +22 -0
- package/src/remote/version.ts +12 -0
- package/src/remote/wire.ts +48 -0
- package/src/stories/chat-panel-layout.stories.tsx +145 -0
- package/src/stories/chat-scene.tsx +571 -0
- package/src/stories/checkpoint-restore.stories.tsx +256 -0
- package/src/stories/context-usage.stories.tsx +212 -0
- package/src/stories/conversation-with-reasoning.stories.tsx +182 -0
- package/src/stories/conversation-with-sources.stories.tsx +471 -0
- package/src/stories/docs/Accessibility.mdx +119 -0
- package/src/stories/docs/ChildElements.mdx +269 -0
- package/src/stories/docs/ForAIAgents.mdx +162 -0
- package/src/stories/docs/GettingStarted.mdx +65 -0
- package/src/stories/docs/Installation.mdx +83 -0
- package/src/stories/docs/Introduction.mdx +50 -0
- package/src/stories/docs/SolidJsAdvanced.mdx +17 -0
- package/src/stories/docs/Theming.mdx +85 -0
- package/src/stories/docs/element-controls.ts +121 -0
- package/src/stories/docs/frameworks/Angular.mdx +245 -0
- package/src/stories/docs/frameworks/Html.mdx +227 -0
- package/src/stories/docs/frameworks/Overview.mdx +47 -0
- package/src/stories/docs/frameworks/React.mdx +227 -0
- package/src/stories/docs/frameworks/Solid.mdx +173 -0
- package/src/stories/docs/frameworks/Svelte.mdx +194 -0
- package/src/stories/docs/frameworks/Vue.mdx +238 -0
- package/src/stories/docs/generative-ui-overview.mdx +186 -0
- package/src/stories/docs/recipes/SpeechToText.mdx +7 -0
- package/src/stories/docs/recipes/Streaming.mdx +68 -0
- package/src/stories/docs/recipes/TextToSpeech.mdx +35 -0
- package/src/stories/docs/theme-editor/canvas.tsx +32 -0
- package/src/stories/docs/theme-editor/inspector.tsx +66 -0
- package/src/stories/docs/theme-editor/presets.test.ts +32 -0
- package/src/stories/docs/theme-editor/presets.ts +64 -0
- package/src/stories/docs/theme-editor/theme-css.test.ts +19 -0
- package/src/stories/docs/theme-editor/theme-css.ts +15 -0
- package/src/stories/docs/theme-editor/theme-editor.tsx +146 -0
- package/src/stories/docs/theme-tokens.tsx +174 -0
- package/src/stories/examples/ChoosingComponents.mdx +106 -0
- package/src/stories/examples/sample-data.ts +79 -0
- package/src/stories/examples/usage/checkpoint-restore.ts +156 -0
- package/src/stories/examples/usage/context-usage.ts +591 -0
- package/src/stories/examples/usage/conversation-with-reasoning.ts +224 -0
- package/src/stories/examples/usage/conversation-with-sources.ts +589 -0
- package/src/stories/examples/usage/empty-state.ts +144 -0
- package/src/stories/examples/usage/full-chat-app.ts +277 -0
- package/src/stories/examples/usage/index.ts +63 -0
- package/src/stories/examples/usage/message-actions.ts +704 -0
- package/src/stories/examples/usage/pattern-centered-conversation.ts +446 -0
- package/src/stories/examples/usage/pattern-chat-panel-layout.ts +442 -0
- package/src/stories/examples/usage/pattern-docked-widget.ts +479 -0
- package/src/stories/examples/usage/prompt-input-variants.ts +1356 -0
- package/src/stories/examples/usage/streaming-response.ts +687 -0
- package/src/stories/examples/usage/types.ts +33 -0
- package/src/stories/full-chat.stories.tsx +18 -0
- package/src/stories/message-actions.stories.tsx +230 -0
- 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/prompt-input-variants.stories.tsx +456 -0
- package/src/stories/streaming-response.stories.tsx +438 -0
- package/src/stories/theme-editor.stories.tsx +16 -0
- package/src/stories/token-reference.stories.tsx +18 -0
- package/src/stories/typography.stories.tsx +78 -0
- package/src/types.ts +47 -0
- package/src/ui/action-icons.ts +52 -0
- package/src/ui/avatar.stories.tsx +103 -0
- package/src/ui/avatar.tsx +23 -0
- package/src/ui/badge.stories.tsx +86 -0
- package/src/ui/badge.tsx +21 -0
- package/src/ui/button.stories.tsx +145 -0
- package/src/ui/button.tsx +38 -0
- package/src/ui/collapsible.stories.tsx +69 -0
- package/src/ui/collapsible.tsx +125 -0
- package/src/ui/dropdown.stories.tsx +59 -0
- package/src/ui/dropdown.tsx +196 -0
- package/src/ui/hover-card.stories.tsx +77 -0
- package/src/ui/hover-card.test.tsx +30 -0
- package/src/ui/hover-card.tsx +172 -0
- package/src/ui/overlay.stories.tsx +115 -0
- package/src/ui/overlay.tsx +158 -0
- package/src/ui/popover.stories.tsx +81 -0
- package/src/ui/popover.test.tsx +99 -0
- package/src/ui/popover.tsx +92 -0
- package/src/ui/resizable.stories.tsx +236 -0
- package/src/ui/resizable.tsx +576 -0
- package/src/ui/scroll-area.stories.tsx +50 -0
- package/src/ui/scroll-area.tsx +15 -0
- package/src/ui/separator.stories.tsx +81 -0
- package/src/ui/separator.tsx +10 -0
- package/src/ui/skeleton.stories.tsx +337 -0
- package/src/ui/skeleton.tsx +16 -0
- package/src/ui/switch.stories.tsx +51 -0
- package/src/ui/switch.test.tsx +59 -0
- package/src/ui/switch.tsx +62 -0
- package/src/ui/textarea.stories.tsx +76 -0
- package/src/ui/textarea.tsx +21 -0
- package/src/ui/tooltip.stories.tsx +74 -0
- package/src/ui/tooltip.tsx +68 -0
- package/src/utils/cn.ts +24 -0
- package/theme.css +187 -0
package/llms.txt
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
|
|
2
|
+
# @kitn.ai/ui
|
|
3
|
+
|
|
4
|
+
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 44 `kitn-*` custom elements: 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
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @kitn.ai/ui
|
|
10
|
+
# SolidJS consumers also need the peer dep:
|
|
11
|
+
npm install solid-js
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## #1 rule: array/object data goes on JS PROPERTIES, not HTML attributes
|
|
15
|
+
|
|
16
|
+
This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `slashCommands`, …) MUST be assigned as JavaScript properties on the element. They CANNOT be passed as HTML attributes — an HTML attribute is always a string and will be ignored or mis-parsed.
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
const chat = document.querySelector('kai-chat');
|
|
20
|
+
chat.messages = [{ id: '1', role: 'assistant', content: 'Hi!' }]; // ✅ property
|
|
21
|
+
```
|
|
22
|
+
```html
|
|
23
|
+
<kai-chat messages="[...]"></kai-chat> <!-- ❌ never works -->
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Only scalar values (string/number/boolean) work as attributes (e.g. `placeholder`, `loading`, `theme`).
|
|
27
|
+
|
|
28
|
+
## Two layers
|
|
29
|
+
|
|
30
|
+
**Layer 1 — batteries-included web components** (`import '@kitn.ai/ui/elements'`):
|
|
31
|
+
Drop an element into any framework (React, Vue, plain HTML). Data in via JS properties; interactions out via non-bubbling CustomEvents.
|
|
32
|
+
|
|
33
|
+
- `<kai-chat>` — full chat UI (message list + prompt input). The primary starting point.
|
|
34
|
+
- `<kai-conversations>` — sidebar conversation browser with group support.
|
|
35
|
+
- `<kai-prompt-input>` — standalone composer with send button.
|
|
36
|
+
|
|
37
|
+
**Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
|
|
38
|
+
All 44 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
|
+
|
|
40
|
+
## Key rules for the web components
|
|
41
|
+
|
|
42
|
+
1. **Array/object data = JS properties** (see above). Scalars may be attributes.
|
|
43
|
+
2. **Events are non-bubbling `CustomEvent`s** — listen directly on the element:
|
|
44
|
+
`chat.addEventListener('kai-submit', (e) => console.log(e.detail.value))`
|
|
45
|
+
3. **`theme` attribute** (`'light' | 'dark' | 'auto'`) works on every element. Default `auto` follows `prefers-color-scheme`.
|
|
46
|
+
4. **Theming via CSS custom properties** — override `--kai-color-*` tokens on `:root`; they pierce Shadow DOM.
|
|
47
|
+
|
|
48
|
+
## ChatMessage schema (required for `<kai-chat>`)
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
interface ChatMessage {
|
|
52
|
+
id: string;
|
|
53
|
+
role: 'user' | 'assistant';
|
|
54
|
+
content: string;
|
|
55
|
+
reasoning?: { text: string; label?: string };
|
|
56
|
+
tools?: ToolPart[];
|
|
57
|
+
attachments?: AttachmentData[];
|
|
58
|
+
actions?: ('copy' | 'like' | 'dislike' | 'regenerate' | 'edit')[];
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Framework wiring
|
|
63
|
+
|
|
64
|
+
**Plain HTML / CDN**
|
|
65
|
+
```html
|
|
66
|
+
<script type="module" src="https://unpkg.com/@kitn.ai/ui/elements"></script>
|
|
67
|
+
<kai-chat style="display:block;height:100vh"></kai-chat>
|
|
68
|
+
<script type="module">
|
|
69
|
+
const chat = document.querySelector('kai-chat');
|
|
70
|
+
chat.messages = [];
|
|
71
|
+
</script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**React** — typed wrappers auto-set properties and expose `on<Event>` props:
|
|
75
|
+
```tsx
|
|
76
|
+
import { Chat } from '@kitn.ai/ui/react';
|
|
77
|
+
<Chat messages={messages} onSubmit={(e) => send(e.detail.value)} />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Vue** — use the element directly; pass arrays via `.prop`:
|
|
81
|
+
```vue
|
|
82
|
+
<kai-chat :messages.prop="messages" @kai-submit="send" />
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Theming
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
:root {
|
|
89
|
+
--kai-color-background: #0f0f0f;
|
|
90
|
+
--kai-color-primary: #7c3aed;
|
|
91
|
+
--kai-color-muted: #1e1e1e;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For plain HTML/CDN: `<link rel="stylesheet" href="…/@kitn.ai/ui/theme.tokens.css">`.
|
|
96
|
+
For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
|
|
97
|
+
|
|
98
|
+
## Docs
|
|
99
|
+
|
|
100
|
+
- Full element reference (all 44 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
|
|
101
|
+
- Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
|
|
102
|
+
- Working examples: https://github.com/kitn-ai/ui/tree/main/examples
|
|
103
|
+
- Storybook: https://storybook.kitn.dev
|
|
104
|
+
- Repository: https://github.com/kitn-ai/ui
|
package/package.json
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kitn.ai/ui",
|
|
3
|
+
"version": "0.14.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"web-components",
|
|
8
|
+
"custom-elements",
|
|
9
|
+
"shadow-dom",
|
|
10
|
+
"ai",
|
|
11
|
+
"chat",
|
|
12
|
+
"chatbot",
|
|
13
|
+
"llm",
|
|
14
|
+
"chat-ui",
|
|
15
|
+
"streaming",
|
|
16
|
+
"markdown",
|
|
17
|
+
"framework-agnostic",
|
|
18
|
+
"react",
|
|
19
|
+
"vue",
|
|
20
|
+
"angular",
|
|
21
|
+
"svelte",
|
|
22
|
+
"solid-js"
|
|
23
|
+
],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"homepage": "https://ui.kitn.ai",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/kitn-ai/ui.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/kitn-ai/ui/issues"
|
|
32
|
+
},
|
|
33
|
+
"main": "src/index.ts",
|
|
34
|
+
"types": "src/index.ts",
|
|
35
|
+
"unpkg": "./dist/kitn-chat.es.js",
|
|
36
|
+
"jsdelivr": "./dist/kitn-chat.es.js",
|
|
37
|
+
"customElements": "dist/custom-elements.json",
|
|
38
|
+
"exports": {
|
|
39
|
+
".": "./src/index.ts",
|
|
40
|
+
"./elements": {
|
|
41
|
+
"types": "./src/elements/element-types.d.ts",
|
|
42
|
+
"default": "./dist/kitn-chat.es.js"
|
|
43
|
+
},
|
|
44
|
+
"./theme.css": "./theme.css",
|
|
45
|
+
"./theme.tokens.css": "./dist/theme.tokens.css",
|
|
46
|
+
"./react": "./frameworks/react/index.tsx",
|
|
47
|
+
"./provider": {
|
|
48
|
+
"types": "./dist/kitn-chat-provider.d.ts",
|
|
49
|
+
"default": "./dist/kitn-chat-provider.es.js"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist",
|
|
54
|
+
"src",
|
|
55
|
+
"frameworks",
|
|
56
|
+
"theme.css",
|
|
57
|
+
"llms.txt",
|
|
58
|
+
"llms-full.txt"
|
|
59
|
+
],
|
|
60
|
+
"scripts": {
|
|
61
|
+
"prepublishOnly": "npm run build",
|
|
62
|
+
"prebuild": "npm run build:css",
|
|
63
|
+
"build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts",
|
|
64
|
+
"postbuild": "npm run build:theme && npm run build:api && npm run build:schemas",
|
|
65
|
+
"build:theme": "node scripts/build-theme-tokens.mjs",
|
|
66
|
+
"build:api": "node scripts/gen-element-api.mjs",
|
|
67
|
+
"build:schemas": "node scripts/copy-card-schemas.mjs",
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"test:react": "vitest run --config vitest.react.config.ts",
|
|
70
|
+
"test:storybook": "vitest run --project=storybook",
|
|
71
|
+
"test:watch": "vitest",
|
|
72
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.react.json && tsc --noEmit -p tsconfig.react.test.json",
|
|
73
|
+
"examples": "echo 'Serving repo root on http://localhost:8000 — open http://localhost:8000/examples/composable/index.html' && python3 -m http.server 8000",
|
|
74
|
+
"dev": "npm run build:css && storybook dev -p 6006",
|
|
75
|
+
"storybook": "npm run build:css && storybook dev -p 6006",
|
|
76
|
+
"build-storybook": "npm run build:css && storybook build",
|
|
77
|
+
"build:css": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --minify",
|
|
78
|
+
"build:css:watch": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --watch",
|
|
79
|
+
"dev:provider": "vite examples/remote-provider --port 6007 --strictPort",
|
|
80
|
+
"dev:host": "vite examples/remote-host --port 6006 --strictPort",
|
|
81
|
+
"test:e2e": "playwright test"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"@floating-ui/dom": "^1.7.6",
|
|
85
|
+
"@shikijs/langs": "^4.2.0",
|
|
86
|
+
"@shikijs/themes": "^4.2.0",
|
|
87
|
+
"class-variance-authority": "^0.7.0",
|
|
88
|
+
"clsx": "^2.1.0",
|
|
89
|
+
"lucide-solid": "^0.400.0",
|
|
90
|
+
"marked": "^18.0.0",
|
|
91
|
+
"shiki": "^4.0.2",
|
|
92
|
+
"solid-element": "^1.9.1",
|
|
93
|
+
"solid-js": "^1.9.0",
|
|
94
|
+
"tailwind-merge": "^2.5.0"
|
|
95
|
+
},
|
|
96
|
+
"devDependencies": {
|
|
97
|
+
"@playwright/test": "^1.60.0",
|
|
98
|
+
"@solidjs/testing-library": "^0.8.0",
|
|
99
|
+
"@storybook/addon-a11y": "^10.4.2",
|
|
100
|
+
"@storybook/addon-docs": "^10.3.5",
|
|
101
|
+
"@storybook/addon-themes": "^10.3.5",
|
|
102
|
+
"@storybook/addon-vitest": "^10.3.5",
|
|
103
|
+
"@tailwindcss/cli": "^4.3.0",
|
|
104
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
105
|
+
"@tailwindcss/typography": "^0.5.19",
|
|
106
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
107
|
+
"@testing-library/react": "^16.3.2",
|
|
108
|
+
"@types/react": "^19.2.17",
|
|
109
|
+
"@types/react-dom": "^19.2.3",
|
|
110
|
+
"@vitejs/plugin-react": "^4.7.0",
|
|
111
|
+
"@vitest/browser-playwright": "4.1.2",
|
|
112
|
+
"@vitest/coverage-v8": "4.1.2",
|
|
113
|
+
"axe-core": "^4.12.1",
|
|
114
|
+
"concurrently": "^10.0.3",
|
|
115
|
+
"http-server": "^14.1.1",
|
|
116
|
+
"jsdom": "^24.0.0",
|
|
117
|
+
"playwright": "^1.59.1",
|
|
118
|
+
"react": "^19.2.7",
|
|
119
|
+
"react-dom": "^19.2.7",
|
|
120
|
+
"remark-gfm": "^4.0.1",
|
|
121
|
+
"storybook": "^10.3.5",
|
|
122
|
+
"storybook-dark-mode": "^5.0.0",
|
|
123
|
+
"storybook-solidjs-vite": "^10.0.12",
|
|
124
|
+
"tailwindcss": "^4.2.2",
|
|
125
|
+
"tw-animate-css": "^1.4.0",
|
|
126
|
+
"typescript": "^5.5.0",
|
|
127
|
+
"vite": "^6.0.0",
|
|
128
|
+
"vite-plugin-dts": "^4.5.4",
|
|
129
|
+
"vite-plugin-solid": "^2.11.0",
|
|
130
|
+
"vitest": "^4.1.0"
|
|
131
|
+
},
|
|
132
|
+
"peerDependencies": {
|
|
133
|
+
"react": ">=18",
|
|
134
|
+
"solid-js": "^1.9.0"
|
|
135
|
+
},
|
|
136
|
+
"peerDependenciesMeta": {
|
|
137
|
+
"react": {
|
|
138
|
+
"optional": true
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from 'storybook-solidjs-vite';
|
|
2
|
+
import { createSignal } from 'solid-js';
|
|
3
|
+
import { Artifact, type ArtifactFile, type ArtifactTab } from './artifact';
|
|
4
|
+
import { componentDescription } from '../stories/docs/element-controls';
|
|
5
|
+
|
|
6
|
+
// Storybook serves examples/artifact-fixtures at /artifact-fixtures.
|
|
7
|
+
const BASE = new URL('artifact-fixtures', document.baseURI).href;
|
|
8
|
+
|
|
9
|
+
const FILES: ArtifactFile[] = [
|
|
10
|
+
{
|
|
11
|
+
path: 'index.html',
|
|
12
|
+
url: `${BASE}/index.html`,
|
|
13
|
+
type: 'html',
|
|
14
|
+
language: 'html',
|
|
15
|
+
code: `<!DOCTYPE html>\n<html lang="en">\n <head><link rel="stylesheet" href="css/site.css" /></head>\n <body><h1>Starboard</h1><a href="about.html">About</a></body>\n</html>`,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
path: 'about.html',
|
|
19
|
+
url: `${BASE}/about.html`,
|
|
20
|
+
type: 'html',
|
|
21
|
+
language: 'html',
|
|
22
|
+
code: `<!DOCTYPE html>\n<html lang="en">\n <body data-page="about"><h1>About</h1><a href="index.html">Home</a></body>\n</html>`,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
path: 'css/site.css',
|
|
26
|
+
url: `${BASE}/css/site.css`,
|
|
27
|
+
type: 'other',
|
|
28
|
+
language: 'css',
|
|
29
|
+
code: `:root { --accent: #6ea8fe; }\nbody { font-family: system-ui, sans-serif; }`,
|
|
30
|
+
},
|
|
31
|
+
{ path: 'assets/logo.svg', url: `${BASE}/assets/logo.svg`, type: 'image' },
|
|
32
|
+
{ path: 'assets/report.pdf', url: `${BASE}/assets/report.pdf`, type: 'pdf' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const meta = {
|
|
36
|
+
title: 'Solid (Advanced)/Elements/Artifact',
|
|
37
|
+
component: Artifact,
|
|
38
|
+
tags: ['autodocs'],
|
|
39
|
+
parameters: {
|
|
40
|
+
layout: 'padded',
|
|
41
|
+
docs: {
|
|
42
|
+
description: componentDescription([
|
|
43
|
+
'A framed, switchable **generated-artifact viewer** — the "canvas / artifacts" pattern. A sandboxed `<iframe>` with a functional nav toolbar (back · forward · reload · home + editable path field) and a **Preview | Code** toggle; the Code tab shows a `FileTree` + the active file source via `CodeBlock`.',
|
|
44
|
+
'**When to use:** to show an AI-generated artifact your backend hosts (page, doc, image, PDF) beside the conversation. The component frames; your backend serves — so relative links, back/forward and multi-format work natively.',
|
|
45
|
+
'**How to use:** set `src` to the hosted URL and `files` (`{ path, url?, code?, language?, type? }[]`) for the Code tree. The iframe `sandbox` defaults to `allow-scripts allow-forms` (not `allow-same-origin`). Handle `onNavigate(url)`, `onTabChange(tab)`, `onFileSelect(path)`.',
|
|
46
|
+
'**Placement:** the preview/canvas panel of a chat shell (e.g. `list | chat | artifact`). It **fills** its container — give the parent a height.',
|
|
47
|
+
]),
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
argTypes: {
|
|
51
|
+
files: { control: false },
|
|
52
|
+
src: { control: 'text' },
|
|
53
|
+
tab: { control: 'select', options: ['preview', 'code'] },
|
|
54
|
+
sandbox: { control: 'text' },
|
|
55
|
+
},
|
|
56
|
+
args: { src: `${BASE}/index.html`, files: FILES, tab: 'preview' as ArtifactTab },
|
|
57
|
+
render: (args) => (
|
|
58
|
+
<div class="h-[520px] w-full max-w-[900px]">
|
|
59
|
+
<Artifact
|
|
60
|
+
src={args.src}
|
|
61
|
+
files={args.files}
|
|
62
|
+
tab={args.tab}
|
|
63
|
+
sandbox={args.sandbox}
|
|
64
|
+
iframeTitle="Starboard artifact preview"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
),
|
|
68
|
+
} satisfies Meta<typeof Artifact>;
|
|
69
|
+
|
|
70
|
+
export default meta;
|
|
71
|
+
type Story = StoryObj<typeof meta>;
|
|
72
|
+
|
|
73
|
+
const IMPORT = `import { Artifact } from '@kitn.ai/ui';`;
|
|
74
|
+
const src = (code: string) => ({
|
|
75
|
+
parameters: { docs: { source: { code: `${IMPORT}\n\n${code}`, language: 'tsx' } } },
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export const Playground: Story = {
|
|
79
|
+
...src(`<Artifact src={src} files={files} tab="preview" />`),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const CodeTab: Story = {
|
|
83
|
+
name: 'Code tab',
|
|
84
|
+
args: { tab: 'code' as ArtifactTab },
|
|
85
|
+
render: (args: { src?: string; files: ArtifactFile[] }) => (
|
|
86
|
+
<div class="h-[520px] w-full max-w-[900px]">
|
|
87
|
+
<Artifact src={args.src} files={args.files} tab="code" activeFile="index.html" iframeTitle="Starboard artifact preview" />
|
|
88
|
+
</div>
|
|
89
|
+
),
|
|
90
|
+
...src(`<Artifact src={src} files={files} tab="code" activeFile="index.html" />`),
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Controlled — observe the emitted nav model. */
|
|
94
|
+
export const Controlled: Story = {
|
|
95
|
+
render: () => {
|
|
96
|
+
const [log, setLog] = createSignal<string[]>([]);
|
|
97
|
+
const push = (s: string) => setLog((l) => [s, ...l].slice(0, 6));
|
|
98
|
+
return (
|
|
99
|
+
<div class="flex flex-col gap-2">
|
|
100
|
+
<div class="h-[420px] w-full max-w-[900px]">
|
|
101
|
+
<Artifact
|
|
102
|
+
src={`${BASE}/index.html`}
|
|
103
|
+
files={FILES}
|
|
104
|
+
iframeTitle="Starboard artifact preview"
|
|
105
|
+
onNavigate={(url) => push(`navigate → ${url}`)}
|
|
106
|
+
onTabChange={(t) => push(`kai-tab-change → ${t}`)}
|
|
107
|
+
onFileSelect={(p) => push(`kai-file-select → ${p}`)}
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
<pre class="m-0 min-h-24 max-w-[900px] rounded-lg bg-muted px-3 py-2.5 text-xs text-muted-foreground">
|
|
111
|
+
{log().length ? log().join('\n') : '(navigate the preview / switch tabs / pick a file…)'}
|
|
112
|
+
</pre>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
...src(`<Artifact src={src} files={files}
|
|
117
|
+
onNavigate={(url) => …} onTabChange={(t) => …} onFileSelect={(p) => …} />`),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/** PDFs render inline via pdf.js (loaded on demand from a CDN). */
|
|
121
|
+
export const PdfPreview: Story = {
|
|
122
|
+
name: 'PDF (inline)',
|
|
123
|
+
render: () => (
|
|
124
|
+
<div class="h-[520px] w-full max-w-[900px]">
|
|
125
|
+
<Artifact src={`${BASE}/assets/report.pdf`} files={FILES} />
|
|
126
|
+
</div>
|
|
127
|
+
),
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/** Fallback card when inline rendering can't work (here the src 404s). */
|
|
131
|
+
export const PdfFallback: Story = {
|
|
132
|
+
name: 'PDF (fallback card)',
|
|
133
|
+
render: () => (
|
|
134
|
+
<div class="h-[520px] w-full max-w-[900px]">
|
|
135
|
+
<Artifact src={`${BASE}/assets/does-not-exist.pdf`} />
|
|
136
|
+
</div>
|
|
137
|
+
),
|
|
138
|
+
};
|